From 01758ed3323e22359f685ffb37ef42a3b856fd66 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 12 Apr 2013 00:21:49 +0200 Subject: [PATCH] Rework SolverPackageSpecifier * It no longer consists of a BPackageResolvableExpression and a repository. Instead it can now either refer to a package directly or consist of a search string. * SolverPackageSpecifierList: Add AppendSpecifier() convenience versions. * Adjust LibsolvSolver and pkgman accordingly. --- .../package/solver/SolverPackageSpecifier.h | 32 ++++--- .../solver/SolverPackageSpecifierList.h | 5 +- .../pkgman/command_resolve_dependencies.cpp | 6 +- src/kits/package/solver/LibsolvSolver.cpp | 88 +++++++++++++------ src/kits/package/solver/LibsolvSolver.h | 3 + .../package/solver/SolverPackageSpecifier.cpp | 50 ++++++----- .../solver/SolverPackageSpecifierList.cpp | 14 +++ 7 files changed, 132 insertions(+), 66 deletions(-) diff --git a/headers/os/package/solver/SolverPackageSpecifier.h b/headers/os/package/solver/SolverPackageSpecifier.h index cfef5849a2..0f4dd89754 100644 --- a/headers/os/package/solver/SolverPackageSpecifier.h +++ b/headers/os/package/solver/SolverPackageSpecifier.h @@ -6,38 +6,44 @@ #define _PACKAGE__SOLVER_PACKAGE_SPECIFIER_H_ -#include +#include namespace BPackageKit { -class BSolverRepository; +class BSolverPackage; class BSolverPackageSpecifier { +public: + enum BType { + B_UNSPECIFIED, + B_PACKAGE, + B_SELECT_STRING + }; + public: BSolverPackageSpecifier(); - BSolverPackageSpecifier( - const BPackageResolvableExpression& - expression); - BSolverPackageSpecifier( - BSolverRepository* repository, - const BPackageResolvableExpression& - expression); + explicit BSolverPackageSpecifier( + BSolverPackage* package); + explicit BSolverPackageSpecifier( + const BString& selectString); BSolverPackageSpecifier( const BSolverPackageSpecifier& other); ~BSolverPackageSpecifier(); - BSolverRepository* Repository() const; - const BPackageResolvableExpression& Expression() const; + BType Type() const; + BSolverPackage* Package() const; + const BString& SelectString() const; BSolverPackageSpecifier& operator=( const BSolverPackageSpecifier& other); private: - BSolverRepository* fRepository; - BPackageResolvableExpression fExpression; + BType fType; + BSolverPackage* fPackage; + BString fSelectString; }; diff --git a/headers/os/package/solver/SolverPackageSpecifierList.h b/headers/os/package/solver/SolverPackageSpecifierList.h index 7a2bf581e1..9a4d582c47 100644 --- a/headers/os/package/solver/SolverPackageSpecifierList.h +++ b/headers/os/package/solver/SolverPackageSpecifierList.h @@ -6,12 +6,13 @@ #define _PACKAGE__SOLVER_PACKAGE_SPECIFIER_LIST_H_ -#include +#include namespace BPackageKit { +class BSolverPackage; class BSolverPackageSpecifier; @@ -28,6 +29,8 @@ public: bool AppendSpecifier( const BSolverPackageSpecifier& specifier); + bool AppendSpecifier(BSolverPackage* package); + bool AppendSpecifier(const BString& selectString); void MakeEmpty(); BSolverPackageSpecifierList& operator=( diff --git a/src/bin/pkgman/command_resolve_dependencies.cpp b/src/bin/pkgman/command_resolve_dependencies.cpp index 9e67ced5a8..e585f6dea4 100644 --- a/src/bin/pkgman/command_resolve_dependencies.cpp +++ b/src/bin/pkgman/command_resolve_dependencies.cpp @@ -182,12 +182,8 @@ command_resolve_dependencies(int argc, const char* const* argv) // resolve BSolverPackageSpecifierList packagesToInstall; - if (!packagesToInstall.AppendSpecifier( - BSolverPackageSpecifier(&dummyRepository, - BPackageResolvableExpression( - specifiedPackage->Info().Name())))) { + if (!packagesToInstall.AppendSpecifier(specifiedPackage)) DIE(B_NO_MEMORY, "failed to add specified package"); - } error = solver->Install(packagesToInstall); if (error != B_OK) diff --git a/src/kits/package/solver/LibsolvSolver.cpp b/src/kits/package/solver/LibsolvSolver.cpp index 66c3a78e24..a8efa8e37b 100644 --- a/src/kits/package/solver/LibsolvSolver.cpp +++ b/src/kits/package/solver/LibsolvSolver.cpp @@ -162,6 +162,7 @@ LibsolvSolver::LibsolvSolver() fRepositoryInfos(10, true), fInstalledRepository(NULL), fSolvablePackages(), + fPackageSolvables(), fProblems(10, true) { } @@ -299,38 +300,61 @@ LibsolvSolver::Install(const BSolverPackageSpecifierList& packages) int32 packageCount = packages.CountSpecifiers(); for (int32 i = 0; i < packageCount; i++) { const BSolverPackageSpecifier& specifier = *packages.SpecifierAt(i); - - // find matching packages - SolvQueue matchingPackages; - - int flags = SELECTION_NAME | SELECTION_PROVIDES | SELECTION_GLOB - | SELECTION_CANON | SELECTION_DOTARCH | SELECTION_REL; -// TODO: All flags needed/useful? - /*int matchFlags =*/ selection_make(fPool, &matchingPackages, - specifier.Expression().Name(), flags); -// TODO: Don't just match the name, but also the version, if given! - if (matchingPackages.count == 0) - return B_NAME_NOT_FOUND; - - // restrict to the matching repository - if (BSolverRepository* repository = specifier.Repository()) { - RepositoryInfo* repositoryInfo = _GetRepositoryInfo(repository); - if (repositoryInfo == NULL) + switch (specifier.Type()) { + case BSolverPackageSpecifier::B_UNSPECIFIED: return B_BAD_VALUE; - SolvQueue repoFilter; - queue_push2(&repoFilter, - SOLVER_SOLVABLE_REPO/* | SOLVER_SETREPO | SOLVER_SETVENDOR*/, - repositoryInfo->SolvRepo()->repoid); + case BSolverPackageSpecifier::B_PACKAGE: + { + BSolverPackage* package = specifier.Package(); + Solvable* solvable; + if (package == NULL + || (solvable = _GetSolvable(package)) == NULL) { + return B_BAD_VALUE; + } - selection_filter(fPool, &matchingPackages, &repoFilter); + queue_push2(&jobs, SOLVER_SOLVABLE, + fPool->solvables - solvable); + break; + } + + case BSolverPackageSpecifier::B_SELECT_STRING: + { + // find matching packages + SolvQueue matchingPackages; + + int flags = SELECTION_NAME | SELECTION_PROVIDES | SELECTION_GLOB + | SELECTION_CANON | SELECTION_DOTARCH | SELECTION_REL; + /*int matchFlags =*/ selection_make(fPool, &matchingPackages, + specifier.SelectString().String(), flags); + if (matchingPackages.count == 0) + return B_NAME_NOT_FOUND; +// TODO: We might want to add support for restricting to certain repositories. +#if 0 + // restrict to the matching repository + if (BSolverRepository* repository = specifier.Repository()) { + RepositoryInfo* repositoryInfo + = _GetRepositoryInfo(repository); + if (repositoryInfo == NULL) + return B_BAD_VALUE; - if (matchingPackages.count == 0) - return B_NAME_NOT_FOUND; + SolvQueue repoFilter; + queue_push2(&repoFilter, + SOLVER_SOLVABLE_REPO + /* | SOLVER_SETREPO | SOLVER_SETVENDOR*/, + repositoryInfo->SolvRepo()->repoid); + + selection_filter(fPool, &matchingPackages, &repoFilter); + + if (matchingPackages.count == 0) + return B_NAME_NOT_FOUND; + } +#endif + + for (int j = 0; j < matchingPackages.count; j++) + queue_push(&jobs, matchingPackages.elements[j]); + } } - - for (int j = 0; j < matchingPackages.count; j++) - queue_push(&jobs, matchingPackages.elements[j]); } // set jobs' solver mode and solve @@ -506,6 +530,7 @@ LibsolvSolver::_CleanupPool() // clean up our data structures that depend on/refer to libsolv pool data fSolvablePackages.clear(); + fPackageSolvables.clear(); int32 repositoryCount = fRepositoryInfos.CountItems(); for (int32 i = 0; i < repositoryCount; i++) @@ -575,6 +600,7 @@ LibsolvSolver::_AddRepositories() try { fSolvablePackages[solvable] = package; + fPackageSolvables[package] = solvable; } catch (std::bad_alloc&) { return B_NO_MEMORY; } @@ -625,6 +651,14 @@ LibsolvSolver::_GetPackage(Id solvableId) const } +Solvable* +LibsolvSolver::_GetSolvable(BSolverPackage* package) const +{ + PackageMap::const_iterator it = fPackageSolvables.find(package); + return it != fPackageSolvables.end() ? it->second : NULL; +} + + status_t LibsolvSolver::_AddProblem(Id problemId) { diff --git a/src/kits/package/solver/LibsolvSolver.h b/src/kits/package/solver/LibsolvSolver.h index eaecd8fdc5..48f76f83fb 100644 --- a/src/kits/package/solver/LibsolvSolver.h +++ b/src/kits/package/solver/LibsolvSolver.h @@ -58,6 +58,7 @@ private: typedef BObjectList RepositoryInfoList; typedef BObjectList ProblemList; typedef std::map SolvableMap; + typedef std::map PackageMap; private: status_t _InitPool(); @@ -71,6 +72,7 @@ private: BSolverRepository* repository) const; BSolverPackage* _GetPackage(Solvable* solvable) const; BSolverPackage* _GetPackage(Id solvableId) const; + Solvable* _GetSolvable(BSolverPackage* package) const; status_t _AddProblem(Id problemId); status_t _AddSolution(Problem* problem, Id solutionId); @@ -94,6 +96,7 @@ private: RepositoryInfoList fRepositoryInfos; RepositoryInfo* fInstalledRepository; SolvableMap fSolvablePackages; + PackageMap fPackageSolvables; ProblemList fProblems; }; diff --git a/src/kits/package/solver/SolverPackageSpecifier.cpp b/src/kits/package/solver/SolverPackageSpecifier.cpp index c1469d422a..1e3b61d21e 100644 --- a/src/kits/package/solver/SolverPackageSpecifier.cpp +++ b/src/kits/package/solver/SolverPackageSpecifier.cpp @@ -15,26 +15,27 @@ namespace BPackageKit { BSolverPackageSpecifier::BSolverPackageSpecifier() : - fRepository(NULL), - fExpression() + fType(B_UNSPECIFIED), + fPackage(NULL), + fSelectString() { } -BSolverPackageSpecifier::BSolverPackageSpecifier( - const BPackageResolvableExpression& expression) +BSolverPackageSpecifier::BSolverPackageSpecifier(BSolverPackage* package) : - fRepository(NULL), - fExpression(expression) + fType(B_PACKAGE), + fPackage(package), + fSelectString() { } -BSolverPackageSpecifier::BSolverPackageSpecifier(BSolverRepository* repository, - const BPackageResolvableExpression& expression) +BSolverPackageSpecifier::BSolverPackageSpecifier(const BString& selectString) : - fRepository(repository), - fExpression(expression) + fType(B_SELECT_STRING), + fPackage(NULL), + fSelectString() { } @@ -42,8 +43,9 @@ BSolverPackageSpecifier::BSolverPackageSpecifier(BSolverRepository* repository, BSolverPackageSpecifier::BSolverPackageSpecifier( const BSolverPackageSpecifier& other) : - fRepository(other.fRepository), - fExpression(other.fExpression) + fType(other.fType), + fPackage(other.fPackage), + fSelectString(other.fSelectString) { } @@ -53,25 +55,33 @@ BSolverPackageSpecifier::~BSolverPackageSpecifier() } -BSolverRepository* -BSolverPackageSpecifier::Repository() const +BSolverPackageSpecifier::BType +BSolverPackageSpecifier::Type() const { - return fRepository; + return fType; } -const BPackageResolvableExpression& -BSolverPackageSpecifier::Expression() const +BSolverPackage* +BSolverPackageSpecifier::Package() const { - return fExpression; + return fPackage; +} + + +const BString& +BSolverPackageSpecifier::SelectString() const +{ + return fSelectString; } BSolverPackageSpecifier& BSolverPackageSpecifier::operator=(const BSolverPackageSpecifier& other) { - fRepository = other.fRepository; - fExpression = other.fExpression; + fType = other.fType; + fPackage = other.fPackage; + fSelectString = other.fSelectString; return *this; } diff --git a/src/kits/package/solver/SolverPackageSpecifierList.cpp b/src/kits/package/solver/SolverPackageSpecifierList.cpp index 6544179079..69a968354b 100644 --- a/src/kits/package/solver/SolverPackageSpecifierList.cpp +++ b/src/kits/package/solver/SolverPackageSpecifierList.cpp @@ -101,6 +101,20 @@ BSolverPackageSpecifierList::AppendSpecifier( } +bool +BSolverPackageSpecifierList::AppendSpecifier(BSolverPackage* package) +{ + return AppendSpecifier(BSolverPackageSpecifier(package)); +} + + +bool +BSolverPackageSpecifierList::AppendSpecifier(const BString& selectString) +{ + return AppendSpecifier(BSolverPackageSpecifier(selectString)); +} + + void BSolverPackageSpecifierList::MakeEmpty() {