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.
This commit is contained in:
Ingo Weinhold 2013-04-12 00:21:49 +02:00
parent 663e351cb4
commit 01758ed332
7 changed files with 132 additions and 66 deletions

View File

@ -6,38 +6,44 @@
#define _PACKAGE__SOLVER_PACKAGE_SPECIFIER_H_
#include <package/PackageResolvableExpression.h>
#include <String.h>
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;
};

View File

@ -6,12 +6,13 @@
#define _PACKAGE__SOLVER_PACKAGE_SPECIFIER_LIST_H_
#include <SupportDefs.h>
#include <String.h>
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=(

View File

@ -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)

View File

@ -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)
{

View File

@ -58,6 +58,7 @@ private:
typedef BObjectList<RepositoryInfo> RepositoryInfoList;
typedef BObjectList<Problem> ProblemList;
typedef std::map<Solvable*, BSolverPackage*> SolvableMap;
typedef std::map<BSolverPackage*, Solvable*> 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;
};

View File

@ -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;
}

View File

@ -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()
{