diff --git a/libpkg/algo/search.cpp b/libpkg/algo/search.cpp index ebbbb2d..6f2708c 100644 --- a/libpkg/algo/search.cpp +++ b/libpkg/algo/search.cpp @@ -241,9 +241,9 @@ std::vector Config::findPackages( if (!databasePred(db)) { continue; } - db.allPackages([&](StorageID packageID, const std::shared_ptr &package) { + db.allPackages([&](StorageID packageID, std::shared_ptr &&package) { if (packagePred(db, *package)) { - pkgs.emplace_back(db, package, packageID); + pkgs.emplace_back(db, std::move(package), packageID); } return false; }); @@ -258,9 +258,9 @@ std::vector Config::findPackages(const std::function(); for (auto &db : databases) { - db.allPackages([&](StorageID packageID, const std::shared_ptr &package) { + db.allPackages([&](StorageID packageID, std::shared_ptr &&package) { if (pred(db, *package)) { - pkgs.emplace_back(db, package, packageID); + pkgs.emplace_back(db, std::move(package), packageID); } return false; }); diff --git a/libpkg/data/database.cpp b/libpkg/data/database.cpp index 066df3c..3dc6417 100644 --- a/libpkg/data/database.cpp +++ b/libpkg/data/database.cpp @@ -246,7 +246,7 @@ void Database::addPackageDependencies(StorageID packageID, const std::shared_ptr } } -void Database::allPackages(const PackageVisitor &visitor) +void Database::allPackages(const PackageVisitorMove &visitor) { auto txn = m_storage->packages.getROTransaction(); for (auto i = txn.begin(); i != txn.end(); ++i) { @@ -272,7 +272,7 @@ std::size_t Database::packageCount() const return m_storage->packages.getROTransaction().size(); } -void Database::providingPackages(const Dependency &dependency, bool reverse, const PackageVisitor &visitor) +void Database::providingPackages(const Dependency &dependency, bool reverse, const PackageVisitorConst &visitor) { auto providesTxn = (reverse ? m_storage->requiredDeps : m_storage->providedDeps).getROTransaction(); auto packagesTxn = m_storage->packages.getROTransaction(); @@ -283,7 +283,7 @@ void Database::providingPackages(const Dependency &dependency, bool reverse, con continue; } for (const auto packageID : providedDependency.relevantPackages) { - const auto res = m_storage->packageCache.retrieve(*m_storage, &packagesTxn, packageID); + auto res = m_storage->packageCache.retrieve(*m_storage, &packagesTxn, packageID); if (res.pkg && visitor(packageID, res.pkg)) { return; } @@ -291,13 +291,13 @@ void Database::providingPackages(const Dependency &dependency, bool reverse, con } } -void Database::providingPackages(const std::string &libraryName, bool reverse, const PackageVisitor &visitor) +void Database::providingPackages(const std::string &libraryName, bool reverse, const PackageVisitorConst &visitor) { auto providesTxn = (reverse ? m_storage->requiredLibs : m_storage->providedLibs).getROTransaction(); auto packagesTxn = m_storage->packages.getROTransaction(); for (auto [i, end] = providesTxn.equal_range<0>(libraryName); i != end; ++i) { for (const auto packageID : i->relevantPackages) { - const auto res = m_storage->packageCache.retrieve(*m_storage, &packagesTxn, packageID); + auto res = m_storage->packageCache.retrieve(*m_storage, &packagesTxn, packageID); if (res.pkg && visitor(packageID, res.pkg)) { return; } @@ -502,8 +502,9 @@ std::unordered_map Database::detectUnresolv LibPkg::PackageUpdates LibPkg::Database::checkForUpdates(const std::vector &updateSources, UpdateCheckOptions options) { auto results = PackageUpdates(); - allPackages([&](StorageID myPackageID, const std::shared_ptr &package) { + allPackages([&](StorageID myPackageID, std::shared_ptr &&package) { auto regularName = std::string(); + auto used = false; if (options & UpdateCheckOptions::ConsiderRegularPackage) { const auto decomposedName = package->decomposeName(); if ((!decomposedName.targetPrefix.empty() || !decomposedName.vcsSuffix.empty()) && !decomposedName.isVcsPackage()) { @@ -534,37 +535,42 @@ LibPkg::PackageUpdates LibPkg::Database::checkForUpdates(const std::vectoremplace_back( PackageSearchResult(*this, package, myPackageID), PackageSearchResult(*updateSource, updatePackage, updatePackageID)); + used = true; } } if (!foundPackage) { results.orphans.emplace_back(PackageSearchResult(*this, package, myPackageID)); + used = true; } - if (regularName.empty()) { - return false; + if (!regularName.empty()) { + for (auto *const updateSource : updateSources) { + const auto [updatePackageID, updatePackage] = updateSource->findPackageWithID(regularName); + if (!updatePackage) { + continue; + } + const auto versionDiff = package->compareVersion(*updatePackage); + std::vector *list = nullptr; + switch (versionDiff) { + case PackageVersionComparison::SoftwareUpgrade: + list = &results.versionUpdates; + break; + case PackageVersionComparison::PackageUpgradeOnly: + list = &results.packageUpdates; + break; + case PackageVersionComparison::NewerThanSyncVersion: + list = &results.downgrades; + break; + default:; + } + if (list) { + list->emplace_back( + PackageSearchResult(*this, package, myPackageID), PackageSearchResult(*updateSource, updatePackage, updatePackageID)); + used = true; + } + } } - for (auto *const updateSource : updateSources) { - const auto [updatePackageID, updatePackage] = updateSource->findPackageWithID(regularName); - if (!updatePackage) { - continue; - } - const auto versionDiff = package->compareVersion(*updatePackage); - std::vector *list = nullptr; - switch (versionDiff) { - case PackageVersionComparison::SoftwareUpgrade: - list = &results.versionUpdates; - break; - case PackageVersionComparison::PackageUpgradeOnly: - list = &results.packageUpdates; - break; - case PackageVersionComparison::NewerThanSyncVersion: - list = &results.downgrades; - break; - default:; - } - if (list) { - list->emplace_back( - PackageSearchResult(*this, package, myPackageID), PackageSearchResult(*updateSource, updatePackage, updatePackageID)); - } + if (used) { + package.reset(); } return false; }); diff --git a/libpkg/data/database.h b/libpkg/data/database.h index 348fe4b..bfcfcb9 100644 --- a/libpkg/data/database.h +++ b/libpkg/data/database.h @@ -27,6 +27,7 @@ struct LIBPKG_EXPORT DatabaseInfo { struct LIBPKG_EXPORT PackageSearchResult { PackageSearchResult(); PackageSearchResult(Database &database, const std::shared_ptr &package, StorageID id); + PackageSearchResult(Database &database, std::shared_ptr &&package, StorageID id); PackageSearchResult(Database &database, Package &&package, StorageID id); bool operator==(const PackageSearchResult &other) const; @@ -112,7 +113,8 @@ private: }; struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable, public ReflectiveRapidJSON::BinarySerializable { - using PackageVisitor = std::function &)>; + using PackageVisitorMove = std::function &&)>; // package is invalidated/reused unless moved from!!! + using PackageVisitorConst = std::function &)>; using PackageVisitorByName = std::function &)>; friend struct PackageUpdater; @@ -134,11 +136,11 @@ struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable> findPackages(const std::function &pred); void removePackageDependencies(StorageID packageID, const std::shared_ptr &package); void addPackageDependencies(StorageID packageID, const std::shared_ptr &package); - void allPackages(const PackageVisitor &visitor); + void allPackages(const PackageVisitorMove &visitor); void allPackagesByName(const PackageVisitorByName &visitor); std::size_t packageCount() const; - void providingPackages(const Dependency &dependency, bool reverse, const PackageVisitor &visitor); - void providingPackages(const std::string &libraryName, bool reverse, const PackageVisitor &visitor); + void providingPackages(const Dependency &dependency, bool reverse, const PackageVisitorConst &visitor); + void providingPackages(const std::string &libraryName, bool reverse, const PackageVisitorConst &visitor); bool provides(const Dependency &dependency, bool reverse = false) const; bool provides(const std::string &libraryName, bool reverse = false) const; std::shared_ptr findPackage(StorageID packageID); @@ -187,6 +189,13 @@ inline PackageSearchResult::PackageSearchResult(Database &database, const std::s { } +inline PackageSearchResult::PackageSearchResult(Database &database, std::shared_ptr &&package, StorageID id) + : db(&database) + , pkg(std::move(package)) + , id(id) +{ +} + inline PackageSearchResult::PackageSearchResult(Database &database, Package &&package, StorageID id) : db(&database) , pkg(std::make_shared(std::move(package))) diff --git a/librepomgr/buildactions/repomanagement.cpp b/librepomgr/buildactions/repomanagement.cpp index 0b40384..bc512e0 100644 --- a/librepomgr/buildactions/repomanagement.cpp +++ b/librepomgr/buildactions/repomanagement.cpp @@ -451,7 +451,7 @@ void CheckForProblems::run() problems.emplace_back( RepositoryProblem{ .desc = "configured local package directory \"" % db->localPkgDir + "\" is not a directory" }); } - db->allPackages([&](LibPkg::StorageID, const std::shared_ptr &package) { + db->allPackages([&](LibPkg::StorageID, std::shared_ptr &&package) { if (!package->packageInfo) { problems.emplace_back(RepositoryProblem{ .desc = "no package info present", .pkg = package->name }); return false; diff --git a/librepomgr/tests/buildactions.cpp b/librepomgr/tests/buildactions.cpp index 93953df..f8e8527 100644 --- a/librepomgr/tests/buildactions.cpp +++ b/librepomgr/tests/buildactions.cpp @@ -153,7 +153,7 @@ void BuildActionsTests::logTestSetup() { for (auto &db : m_setup.config.databases) { cout << EscapeCodes::Phrases::Info << "Packages of " << db.name << ':' << EscapeCodes::Phrases::End; - db.allPackages([](LibPkg::StorageID, const std::shared_ptr &package) { + db.allPackages([](LibPkg::StorageID, std::shared_ptr &&package) { cout << " - " << package->name << '\n'; return false; }); diff --git a/librepomgr/webclient/aur.cpp b/librepomgr/webclient/aur.cpp index 6ce6791..56d25fa 100644 --- a/librepomgr/webclient/aur.cpp +++ b/librepomgr/webclient/aur.cpp @@ -169,9 +169,9 @@ std::shared_ptr queryAurPackagesForDatabase(LogContext &log, Se configReadLock = &ownConfigReadLock; } auto &aurDb = setup.config.aur; - database.allPackages([&aurDb, &missingPackages](StorageID, const std::shared_ptr &package) { + database.allPackages([&aurDb, &missingPackages](StorageID, std::shared_ptr &&package) { if (const auto aurPackage = aurDb.findPackage(package->name); !aurPackage) { - missingPackages.emplace_back(package->name); + missingPackages.emplace_back(std::move(package->name)); } return false; }); diff --git a/pacfind/main.cpp b/pacfind/main.cpp index a6d4905..f1ae7d7 100644 --- a/pacfind/main.cpp +++ b/pacfind/main.cpp @@ -131,7 +131,7 @@ int main(int argc, const char *argv[]) } } for (auto &db : cfg.databases) { - db.allPackages([&](LibPkg::StorageID, const std::shared_ptr &package) { + db.allPackages([&](LibPkg::StorageID, std::shared_ptr &&package) { const auto &pkgInfo = package->packageInfo; if (!pkgInfo) { return false;