Avoid exceeding txn limit when pulling deps by avoiding recursion

This commit is contained in:
Martchus 2022-02-01 21:30:35 +01:00
parent bb9aaf7839
commit 3f9f5eae3f
2 changed files with 29 additions and 35 deletions

View File

@ -145,41 +145,39 @@ std::vector<Database *> Config::computeDatabasesRequiringDatabase(Database &data
return result;
}
void Config::pullDependentPackages(const std::vector<Dependency> &dependencies, const std::shared_ptr<Package> &relevantPackage,
const std::unordered_set<LibPkg::Database *> &relevantDbs,
std::unordered_map<LibPkg::StorageID, std::shared_ptr<LibPkg::Package>> &runtimeDependencies, DependencySet &missingDependencies,
std::unordered_set<StorageID> &visited)
{
auto found = false;
for (const auto &dependency : dependencies) {
for (auto &db : databases) {
if (relevantDbs.find(&db) == relevantDbs.end()) {
continue;
}
db.providingPackages(dependency, false, [&](StorageID packageID, const std::shared_ptr<Package> &package) {
found = true;
if (visited.emplace(packageID).second) {
const auto &[i, inserted] = runtimeDependencies.try_emplace(packageID);
if (inserted) {
i->second = package;
}
pullDependentPackages(i->second, relevantDbs, runtimeDependencies, missingDependencies, visited);
}
return false;
});
}
if (!found) {
missingDependencies.add(dependency, relevantPackage);
}
}
}
void Config::pullDependentPackages(const std::shared_ptr<Package> &package, const std::unordered_set<LibPkg::Database *> &relevantDbs,
std::unordered_map<LibPkg::StorageID, std::shared_ptr<LibPkg::Package>> &runtimeDependencies, DependencySet &missingDependencies,
std::unordered_set<StorageID> &visited)
{
pullDependentPackages(package->dependencies, package, relevantDbs, runtimeDependencies, missingDependencies, visited);
pullDependentPackages(package->optionalDependencies, package, relevantDbs, runtimeDependencies, missingDependencies, visited);
auto remainingPackages = std::unordered_set<std::shared_ptr<LibPkg::Package>>{ package };
for (auto packageIterator = remainingPackages.begin(); packageIterator != remainingPackages.end(); packageIterator = remainingPackages.begin()) {
const auto &currentPackage = *packageIterator;
for (const auto &dependencies : { currentPackage->dependencies, currentPackage->optionalDependencies }) {
auto found = false;
for (const auto &dependency : dependencies) {
for (auto &db : databases) {
if (relevantDbs.find(&db) == relevantDbs.end()) {
continue;
}
db.providingPackages(dependency, false, [&](StorageID packageID, const std::shared_ptr<Package> &providingPackage) {
found = true;
if (visited.emplace(packageID).second) {
const auto &[i, inserted] = runtimeDependencies.try_emplace(packageID);
if (inserted) {
i->second = providingPackage;
}
remainingPackages.emplace(providingPackage);
}
return false;
});
}
if (!found) {
missingDependencies.add(dependency, currentPackage);
}
}
}
remainingPackages.erase(packageIterator);
}
}
void Config::markAllDatabasesToBeDiscarded()

View File

@ -128,10 +128,6 @@ struct LIBPKG_EXPORT Config : public Lockable, public ReflectiveRapidJSON::Binar
LicenseResult computeLicenseInfo(const std::vector<std::string> &dependencyDenotations);
std::variant<std::vector<Database *>, std::string> computeDatabaseDependencyOrder(Database &database, bool addSelf = true);
std::vector<Database *> computeDatabasesRequiringDatabase(Database &database);
void pullDependentPackages(const std::vector<Dependency> &dependencies, const std::shared_ptr<Package> &relevantPackage,
const std::unordered_set<LibPkg::Database *> &relevantDbs,
std::unordered_map<LibPkg::StorageID, std::shared_ptr<LibPkg::Package>> &runtimeDependencies, DependencySet &missingDependencies,
std::unordered_set<StorageID> &visited);
void pullDependentPackages(const std::shared_ptr<Package> &package, const std::unordered_set<LibPkg::Database *> &relevantDbs,
std::unordered_map<LibPkg::StorageID, std::shared_ptr<LibPkg::Package>> &runtimeDependencies, DependencySet &missingDependencies,
std::unordered_set<StorageID> &visited);