solver: fix package deletion to consier provides properly
parent
6da083fc24
commit
17145f82ae
|
@ -17,10 +17,17 @@
|
||||||
#include "apk_provider_data.h"
|
#include "apk_provider_data.h"
|
||||||
|
|
||||||
struct apk_solver_name_state {
|
struct apk_solver_name_state {
|
||||||
struct list_head dirty_list;
|
|
||||||
struct list_head unresolved_list;
|
|
||||||
struct apk_provider chosen;
|
struct apk_provider chosen;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
struct list_head dirty_list;
|
||||||
|
struct list_head unresolved_list;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
struct apk_name *installed_name;
|
||||||
|
struct apk_package *installed_pkg;
|
||||||
|
};
|
||||||
|
};
|
||||||
unsigned short requirers;
|
unsigned short requirers;
|
||||||
unsigned short merge_depends;
|
unsigned short merge_depends;
|
||||||
unsigned short merge_provides;
|
unsigned short merge_provides;
|
||||||
|
|
|
@ -232,11 +232,10 @@ int apk_solver_commit_changeset(struct apk_database *db,
|
||||||
foreach_array_item(change, changeset->changes) {
|
foreach_array_item(change, changeset->changes) {
|
||||||
count_change(change, &prog.total);
|
count_change(change, &prog.total);
|
||||||
if (change->new_pkg)
|
if (change->new_pkg)
|
||||||
size_diff += change->new_pkg->installed_size;
|
size_diff += change->new_pkg->installed_size / 1024;
|
||||||
if (change->old_pkg)
|
if (change->old_pkg)
|
||||||
size_diff -= change->old_pkg->installed_size;
|
size_diff -= change->old_pkg->installed_size / 1024;
|
||||||
}
|
}
|
||||||
size_diff /= 1024;
|
|
||||||
size_unit = 'K';
|
size_unit = 'K';
|
||||||
if (abs(size_diff) > 10000) {
|
if (abs(size_diff) > 10000) {
|
||||||
size_diff /= 1024;
|
size_diff /= 1024;
|
||||||
|
|
58
src/solver.c
58
src/solver.c
|
@ -665,13 +665,15 @@ static void cset_gen_name_change(struct apk_solver_state *ss, struct apk_name *n
|
||||||
static void cset_gen_name_remove(struct apk_solver_state *ss, struct apk_package *pkg);
|
static void cset_gen_name_remove(struct apk_solver_state *ss, struct apk_package *pkg);
|
||||||
static void cset_gen_dep(struct apk_solver_state *ss, struct apk_package *ppkg, struct apk_dependency *dep);
|
static void cset_gen_dep(struct apk_solver_state *ss, struct apk_package *ppkg, struct apk_dependency *dep);
|
||||||
|
|
||||||
static void cset_track_deps_added(struct apk_dependency_array *deps)
|
static void cset_track_deps_added(struct apk_package *pkg)
|
||||||
{
|
{
|
||||||
struct apk_dependency *d;
|
struct apk_dependency *d;
|
||||||
|
|
||||||
foreach_array_item(d, deps)
|
foreach_array_item(d, pkg->depends) {
|
||||||
if (!d->conflict)
|
if (d->conflict || !d->name->ss.installed_name)
|
||||||
d->name->ss.requirers++;
|
continue;
|
||||||
|
d->name->ss.installed_name->ss.requirers++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cset_track_deps_removed(struct apk_solver_state *ss, struct apk_package *pkg)
|
static void cset_track_deps_removed(struct apk_solver_state *ss, struct apk_package *pkg)
|
||||||
|
@ -680,12 +682,11 @@ static void cset_track_deps_removed(struct apk_solver_state *ss, struct apk_pack
|
||||||
struct apk_package *pkg0;
|
struct apk_package *pkg0;
|
||||||
|
|
||||||
foreach_array_item(d, pkg->depends) {
|
foreach_array_item(d, pkg->depends) {
|
||||||
if (d->conflict)
|
if (d->conflict || !d->name->ss.installed_name)
|
||||||
continue;
|
continue;
|
||||||
d->name->ss.requirers--;
|
if (--d->name->ss.installed_name->ss.requirers > 0)
|
||||||
if (d->name->ss.requirers > 0)
|
|
||||||
continue;
|
continue;
|
||||||
pkg0 = apk_pkg_get_installed(d->name);
|
pkg0 = d->name->ss.installed_pkg;
|
||||||
if (pkg0 != NULL)
|
if (pkg0 != NULL)
|
||||||
cset_gen_name_remove(ss, pkg0);
|
cset_gen_name_remove(ss, pkg0);
|
||||||
}
|
}
|
||||||
|
@ -717,14 +718,10 @@ static void cset_check_install_by_iif(struct apk_solver_state *ss, struct apk_na
|
||||||
|
|
||||||
static void cset_check_removal_by_iif(struct apk_solver_state *ss, struct apk_name *name)
|
static void cset_check_removal_by_iif(struct apk_solver_state *ss, struct apk_name *name)
|
||||||
{
|
{
|
||||||
struct apk_package *pkg;
|
struct apk_package *pkg = name->ss.installed_pkg;
|
||||||
struct apk_dependency *dep0;
|
struct apk_dependency *dep0;
|
||||||
|
|
||||||
if (name->ss.in_changeset || name->ss.chosen.pkg != NULL)
|
if (pkg == NULL || name->ss.in_changeset || name->ss.chosen.pkg != NULL)
|
||||||
return;
|
|
||||||
|
|
||||||
pkg = apk_pkg_get_installed(name);
|
|
||||||
if (pkg == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach_array_item(dep0, pkg->install_if) {
|
foreach_array_item(dep0, pkg->install_if) {
|
||||||
|
@ -748,7 +745,7 @@ static void cset_gen_name_change(struct apk_solver_state *ss, struct apk_name *n
|
||||||
pkg->ss.in_changeset = 1;
|
pkg->ss.in_changeset = 1;
|
||||||
pkg->name->ss.in_changeset = 1;
|
pkg->name->ss.in_changeset = 1;
|
||||||
|
|
||||||
opkg = apk_pkg_get_installed(pkg->name);
|
opkg = pkg->name->ss.installed_pkg;
|
||||||
if (opkg) {
|
if (opkg) {
|
||||||
foreach_array_item(pname, opkg->name->rinstall_if)
|
foreach_array_item(pname, opkg->name->rinstall_if)
|
||||||
cset_check_removal_by_iif(ss, *pname);
|
cset_check_removal_by_iif(ss, *pname);
|
||||||
|
@ -763,7 +760,7 @@ static void cset_gen_name_change(struct apk_solver_state *ss, struct apk_name *n
|
||||||
foreach_array_item(pname, pkg->name->rinstall_if)
|
foreach_array_item(pname, pkg->name->rinstall_if)
|
||||||
cset_check_install_by_iif(ss, *pname);
|
cset_check_install_by_iif(ss, *pname);
|
||||||
|
|
||||||
cset_track_deps_added(pkg->depends);
|
cset_track_deps_added(pkg);
|
||||||
if (opkg)
|
if (opkg)
|
||||||
cset_track_deps_removed(ss, opkg);
|
cset_track_deps_removed(ss, opkg);
|
||||||
}
|
}
|
||||||
|
@ -796,18 +793,35 @@ static void cset_gen_dep(struct apk_solver_state *ss, struct apk_package *ppkg,
|
||||||
mark_error(ss, ppkg);
|
mark_error(ss, ppkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cset_reset_name(apk_hash_item item, void *ctx)
|
||||||
|
{
|
||||||
|
struct apk_name *name = (struct apk_name *) item;
|
||||||
|
name->ss.installed_pkg = NULL;
|
||||||
|
name->ss.installed_name = NULL;
|
||||||
|
name->ss.requirers = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void generate_changeset(struct apk_solver_state *ss, struct apk_dependency_array *world)
|
static void generate_changeset(struct apk_solver_state *ss, struct apk_dependency_array *world)
|
||||||
{
|
{
|
||||||
struct apk_changeset *changeset = ss->changeset;
|
struct apk_changeset *changeset = ss->changeset;
|
||||||
|
struct apk_package *pkg;
|
||||||
struct apk_installed_package *ipkg;
|
struct apk_installed_package *ipkg;
|
||||||
struct apk_dependency *d;
|
struct apk_dependency *d;
|
||||||
|
|
||||||
apk_change_array_init(&changeset->changes);
|
apk_change_array_init(&changeset->changes);
|
||||||
|
|
||||||
|
apk_hash_foreach(&ss->db->available.names, cset_reset_name, NULL);
|
||||||
|
list_for_each_entry(ipkg, &ss->db->installed.packages, installed_pkgs_list) {
|
||||||
|
pkg = ipkg->pkg;
|
||||||
|
pkg->name->ss.installed_pkg = pkg;
|
||||||
|
pkg->name->ss.installed_name = pkg->name;
|
||||||
|
foreach_array_item(d, pkg->provides)
|
||||||
|
if (d->version != &apk_null_blob)
|
||||||
|
d->name->ss.installed_name = pkg->name;
|
||||||
|
}
|
||||||
list_for_each_entry(ipkg, &ss->db->installed.packages, installed_pkgs_list)
|
list_for_each_entry(ipkg, &ss->db->installed.packages, installed_pkgs_list)
|
||||||
ipkg->pkg->name->ss.requirers = 0;
|
cset_track_deps_added(ipkg->pkg);
|
||||||
list_for_each_entry(ipkg, &ss->db->installed.packages, installed_pkgs_list)
|
|
||||||
cset_track_deps_added(ipkg->pkg->depends);
|
|
||||||
list_for_each_entry(ipkg, &ss->db->installed.packages, installed_pkgs_list)
|
list_for_each_entry(ipkg, &ss->db->installed.packages, installed_pkgs_list)
|
||||||
cset_check_removal_by_deps(ss, ipkg->pkg);
|
cset_check_removal_by_deps(ss, ipkg->pkg);
|
||||||
|
|
||||||
|
@ -823,7 +837,7 @@ static void generate_changeset(struct apk_solver_state *ss, struct apk_dependenc
|
||||||
changeset->num_adjust;
|
changeset->num_adjust;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int free_state(apk_hash_item item, void *ctx)
|
static int free_name(apk_hash_item item, void *ctx)
|
||||||
{
|
{
|
||||||
struct apk_name *name = (struct apk_name *) item;
|
struct apk_name *name = (struct apk_name *) item;
|
||||||
memset(&name->ss, 0, sizeof(name->ss));
|
memset(&name->ss, 0, sizeof(name->ss));
|
||||||
|
@ -909,12 +923,12 @@ restart:
|
||||||
dbg_printf("disabling broken world dep: %s", name->name);
|
dbg_printf("disabling broken world dep: %s", name->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apk_hash_foreach(&db->available.names, free_state, NULL);
|
apk_hash_foreach(&db->available.names, free_name, NULL);
|
||||||
apk_hash_foreach(&db->available.packages, free_package, NULL);
|
apk_hash_foreach(&db->available.packages, free_package, NULL);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
apk_hash_foreach(&db->available.names, free_state, NULL);
|
apk_hash_foreach(&db->available.names, free_name, NULL);
|
||||||
apk_hash_foreach(&db->available.packages, free_package, NULL);
|
apk_hash_foreach(&db->available.packages, free_package, NULL);
|
||||||
dbg_printf("solver done, errors=%d\n", ss->errors);
|
dbg_printf("solver done, errors=%d\n", ss->errors);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue