Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MER][T11|T12|T13|T14] Creating the initial problems graph #1891

Merged
merged 30 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0ff0808
add problems graph & problems graph creator
crogoz Aug 31, 2022
9e0be54
new lines & add expanded edges
crogoz Aug 31, 2022
1f864b7
no macros
crogoz Aug 31, 2022
83ebd93
use node accessor
crogoz Sep 1, 2022
0d54e26
Update libmamba/include/mamba/core/problems_graph_util.hpp
crogoz Sep 6, 2022
775909f
Add graph is_reachable algorithm
AntoinePrv Sep 27, 2022
6611338
Add DiGraph [in|out]_degree
AntoinePrv Sep 27, 2022
4f494bb
Fix subdir json creation
AntoinePrv Sep 27, 2022
60681be
Make MPool::select_solvables const
AntoinePrv Sep 15, 2022
ff955b8
Add const convertion operator to mamba::MPool
AntoinePrv Sep 19, 2022
1bcdb79
Add PackageInfo rvalue string ctor
AntoinePrv Sep 27, 2022
39aee75
Simplify problem graph
AntoinePrv Sep 15, 2022
6bdbe4a
Test DependencyInfo
AntoinePrv Sep 27, 2022
018ba48
Add ProblemsGraph ctor from solver
AntoinePrv Sep 19, 2022
5fb898d
Add ProblemsGraph ctor tests
AntoinePrv Sep 27, 2022
12c4ab1
Extend DependencyInfo with build range
AntoinePrv Sep 28, 2022
67ec825
Fix bug in ProblemsGraph
AntoinePrv Sep 29, 2022
52d93dd
Reuse test download cache
AntoinePrv Sep 30, 2022
76d91fe
Add solver_ruleinfo_name
AntoinePrv Oct 5, 2022
ae552ca
Fix ProblemsGraph constructor
AntoinePrv Oct 5, 2022
3988f19
Remove ProblemGraph::ProblemType
AntoinePrv Oct 5, 2022
657760e
Handle Problem constrains through a new type of node
AntoinePrv Oct 5, 2022
1872896
util_random cleanup
AntoinePrv Oct 5, 2022
cf71996
Reuse random string function
AntoinePrv Oct 5, 2022
611f910
Add ProblemsGraph conflcit tests
AntoinePrv Oct 5, 2022
39de2b4
Fix satisfiability_error on various compilers
AntoinePrv Oct 6, 2022
951a986
address comments
crogoz Oct 11, 2022
de33607
Remove trivial use of auto
AntoinePrv Oct 12, 2022
b705492
Add explanation for problem parsing
AntoinePrv Oct 12, 2022
565fa0a
Merge pull request #5 from AntoinePrv/cr/problems-graph-creator
crogoz Oct 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions libmamba/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ set(LIBMAMBA_SOURCES
${LIBMAMBA_SOURCE_DIR}/core/package_cache.cpp
${LIBMAMBA_SOURCE_DIR}/core/pool.cpp
${LIBMAMBA_SOURCE_DIR}/core/prefix_data.cpp
${LIBMAMBA_SOURCE_DIR}/core/problems_graph_util.cpp
${LIBMAMBA_SOURCE_DIR}/core/problems_graph_creator.cpp
${LIBMAMBA_SOURCE_DIR}/core/progress_bar.cpp
${LIBMAMBA_SOURCE_DIR}/core/progress_bar_impl.cpp
${LIBMAMBA_SOURCE_DIR}/core/pinning.cpp
Expand Down Expand Up @@ -193,6 +195,8 @@ set(LIBMAMBA_HEADERS
${LIBMAMBA_INCLUDE_DIR}/mamba/core/fetch.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/core/fsutil.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/core/graph_util.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/core/problems_graph_util.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/core/problems_graph_creator.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/core/history.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/core/link.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/core/mamba_fs.hpp
Expand Down
10 changes: 9 additions & 1 deletion libmamba/include/mamba/core/graph_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ namespace mamba
bool empty() const;
std::size_t number_of_nodes() const;
const node_list& nodes() const;
node_list& nodes();
node_t const& node(node_id id) const;
node_t& node(node_id id);
const node_id_list& successors(node_id id) const;
Expand Down Expand Up @@ -335,6 +336,12 @@ namespace mamba
return m_node_list;
}

template <typename N, typename G>
inline auto DiGraphBase<N, G>::nodes() -> node_list&
crogoz marked this conversation as resolved.
Show resolved Hide resolved
{
return m_node_list;
}

template <typename N, typename G>
inline auto DiGraphBase<N, G>::node(node_id id) const -> node_t const&
{
Expand Down Expand Up @@ -547,7 +554,8 @@ namespace mamba
inline void DiGraph<N, E>::add_edge_impl(node_id from, node_id to, T&& data)
{
Base::add_edge(from, to);
m_edges[{ from, to }] = std::forward<T>(data);
crogoz marked this conversation as resolved.
Show resolved Hide resolved
auto edge_id = std::make_pair(from, to);
m_edges.insert(std::make_pair(edge_id, std::forward<T>(data)));
}

template <typename N, typename E>
Expand Down
142 changes: 142 additions & 0 deletions libmamba/include/mamba/core/problems_graph_creator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright (c) 2019, QuantStack and Mamba Contributors
//
// Distributed under the terms of the BSD 3-Clause License.
//
// The full license is in the file LICENSE, distributed with this software.

#ifndef MAMBA_PROBLEMS_GRAPH_CREATOR_HPP
#define MAMBA_PROBLEMS_GRAPH_CREATOR_HPP

#include <string>
#include <utility>
#include <vector>
#include <regex>
#include <variant>
#include <unordered_set>
crogoz marked this conversation as resolved.
Show resolved Hide resolved

#include "mamba/core/pool.hpp"
#include "mamba/core/problems_graph_util.hpp"
#include "mamba/core/package_info.hpp"
#include "mamba/core/util.hpp"
#include "mamba/core/solver.hpp"

extern "C"
{
#include "solv/solver.h"
}

namespace mamba
{
class MProblemsGraphCreator
{
public:
using graph_t = MProblemsGraph<MNode, MEdge>;
using node_id = MProblemsGraph<MNode, MEdge>::node_id;
using solv_id_to_node_id = std::unordered_map<Id, node_id>;
using problems_list = std::vector<MSolverProblem>;
MProblemsGraphCreator(MPool* pool);

const graph_t& graph_from(const problems_list& problems);
crogoz marked this conversation as resolved.
Show resolved Hide resolved

private:
MPool* m_pool;
graph_t m_problems_graph;
solv_id_to_node_id m_solv_id_to_node_id;
node_id m_root_id;

void add_to_graph(const MSolverProblem& problem);
void add_root_edge(Id target_id, const MNode& target_node, const MEdge& edge);
void add_edge(Id source_id,
const MNode& source_node,
Id target_id,
const MNode& target_node,
const MEdge& edge);
void add_expanded_deps_edges(Id source_id,
const MNode& source_node,
Id dep_id,
const MEdge& edge);
void add_conflicts(Id id1, const MNode& node1, Id id2, const MNode& node2);
node_id get_update_or_create(Id source_id, const MNode& node);
};

inline std::string get_value_or(const std::optional<PackageInfo>& pkg_info)
{
if (pkg_info)
{
return pkg_info.value().str();
}
else
{
return "(null)";
}
}
crogoz marked this conversation as resolved.
Show resolved Hide resolved

template <typename T>
inline bool has_values(const MSolverProblem& problem,
std::initializer_list<std::optional<T>> args)
{
for (const auto& e : args)
{
if (!e)
{
LOG_WARNING << "Unexpected empty optionals for problem " << problem.to_string()
<< "source: " << get_value_or(problem.source())
<< "target: " << get_value_or(problem.target())
<< "dep: " << problem.dep().value_or("(null)") << std::endl;
return false;
}
}
return true;
}

inline std::optional<ProblemType> from(SolverRuleinfo solverRuleInfo)
{
switch (solverRuleInfo)
{
case SOLVER_RULE_PKG_CONSTRAINS:
case SOLVER_RULE_PKG_REQUIRES:
case SOLVER_RULE_JOB:
case SOLVER_RULE_PKG:
case SOLVER_RULE_UPDATE:
return std::nullopt;
;
case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP:
case SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP:
case SOLVER_RULE_JOB_UNKNOWN_PACKAGE:
return ProblemType::NOT_FOUND;
case SOLVER_RULE_PKG_CONFLICTS:
case SOLVER_RULE_PKG_SAME_NAME:
return ProblemType::CONFLICT;
case SOLVER_RULE_BEST:
return ProblemType::BEST_NOT_INSTALLABLE;
case SOLVER_RULE_BLACK:
return ProblemType::ONLY_DIRECT_INSTALL;
case SOLVER_RULE_INFARCH:
return ProblemType::INFERIOR_ARCH;
case SOLVER_RULE_PKG_NOT_INSTALLABLE:
return ProblemType::NOT_INSTALLABLE;
case SOLVER_RULE_STRICT_REPO_PRIORITY:
return ProblemType::EXCLUDED_BY_REPO_PRIORITY;
case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM:
return ProblemType::PROVIDED_BY_SYSTEM;
case SOLVER_RULE_CHOICE:
case SOLVER_RULE_FEATURE:
case SOLVER_RULE_JOB_UNSUPPORTED:
case SOLVER_RULE_LEARNT:
case SOLVER_RULE_PKG_RECOMMENDS:
case SOLVER_RULE_RECOMMENDS:
case SOLVER_RULE_UNKNOWN:
return std::nullopt;
case SOLVER_RULE_PKG_SELF_CONFLICT:
case SOLVER_RULE_PKG_OBSOLETES:
case SOLVER_RULE_PKG_IMPLICIT_OBSOLETES:
case SOLVER_RULE_PKG_INSTALLED_OBSOLETES:
case SOLVER_RULE_YUMOBS:
case SOLVER_RULE_DISTUPGRADE:
return std::nullopt;
}
return std::nullopt;
}
}

#endif // MAMBA_PROBLEMS_GRAPH_CREATOR_HPP
160 changes: 160 additions & 0 deletions libmamba/include/mamba/core/problems_graph_util.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// Copyright (c) 2019, QuantStack and Mamba Contributors
//
// Distributed under the terms of the BSD 3-Clause License.
//
// The full license is in the file LICENSE, distributed with this software.

#ifndef MAMBA_PROBLEMS_GRAPH_HPP
#define MAMBA_PROBLEMS_GRAPH_HPP

#include <string>
#include <utility>
#include <optional>
#include <vector>
#include <regex>
#include <variant>
#include <unordered_set>

#include "mamba/core/graph_util.hpp"
#include "mamba/core/package_info.hpp"

extern "C"
{
#include "solv/solver.h"
}

#define THROWIF(condition, msg) \
{ \
\
if (!condition) \
{ \
std::ostringstream os; \
os << msg; \
throw std::runtime_error(os.str()); \
} \
}

#define THROW(msg) \
{ \
std::ostringstream os; \
os << msg; \
throw std::runtime_error(os.str()); \
}

namespace mamba
{

enum class ProblemType
{
CONFLICT,
NOT_FOUND,
NOT_INSTALLABLE,
BEST_NOT_INSTALLABLE,
ONLY_DIRECT_INSTALL,
EXCLUDED_BY_REPO_PRIORITY,
INFERIOR_ARCH,
PROVIDED_BY_SYSTEM
};

class DependencyInfo
{
public:
DependencyInfo(const std::string& dep);

const std::string& get_name() const;
const std::string& get_range() const;
std::string str() const;

private:
std::string name;
std::string range;
};

namespace NodeInfo
{
struct ResolvedPackage
{
PackageInfo m_package_info;
ResolvedPackage(PackageInfo const& package_info);
crogoz marked this conversation as resolved.
Show resolved Hide resolved
};

struct ProblematicPackage
crogoz marked this conversation as resolved.
Show resolved Hide resolved
{
std::string m_dep;
crogoz marked this conversation as resolved.
Show resolved Hide resolved
ProblematicPackage(std::string const& dep);
crogoz marked this conversation as resolved.
Show resolved Hide resolved
};
struct Root
{
};
}

namespace EdgeInfo
{
struct Require
crogoz marked this conversation as resolved.
Show resolved Hide resolved
{
DependencyInfo m_dep;
Require(DependencyInfo const& dep);
crogoz marked this conversation as resolved.
Show resolved Hide resolved
};
struct Constraint
{
DependencyInfo m_dep;
Constraint(DependencyInfo const& dep);
crogoz marked this conversation as resolved.
Show resolved Hide resolved
};
}

template <class... Ts>
struct overload : Ts...
{
using Ts::operator()...;
};
template <class... Ts>
overload(Ts...) -> overload<Ts...>;

crogoz marked this conversation as resolved.
Show resolved Hide resolved
class MNode
{
public:
using node_info
= std::variant<NodeInfo::ResolvedPackage, NodeInfo::ProblematicPackage, NodeInfo::Root>;
MNode(node_info const& node, std::optional<ProblemType> problem_type = std::nullopt);
void maybe_update_metadata(const MNode& other);

private:
node_info m_info;
std::optional<ProblemType> m_problem_type;
crogoz marked this conversation as resolved.
Show resolved Hide resolved

bool is_root() const;
std::string get_name() const;
std::optional<ProblemType> get_problem_type() const;
};

class MEdge
{
public:
using edge_info = std::variant<EdgeInfo::Require, EdgeInfo::Constraint>;

MEdge(edge_info const& info);
std::string get_info() const;

private:
edge_info m_info;
};
crogoz marked this conversation as resolved.
Show resolved Hide resolved

template <typename T, typename U>
crogoz marked this conversation as resolved.
Show resolved Hide resolved
class MProblemsGraph
{
public:
using graph_t = DiGraph<T, U>;
using node_id = typename DiGraph<T, U>::node_id;
using node_id_conflicts = std::unordered_map<node_id, std::vector<node_id>>;

graph_t& graph();
void add_conflicts(node_id node1, node_id node2);
node_id_conflicts const& get_conflicts() const;

private:
graph_t m_graph;
node_id_conflicts m_node_id_conflicts;
crogoz marked this conversation as resolved.
Show resolved Hide resolved
};
}

#endif // MAMBA_PROBLEMS_GRAPH_HPP
Loading