summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Schroeder <mls@suse.de>2014-03-10 17:38:40 +0100
committerMichael Schroeder <mls@suse.de>2014-03-10 17:38:40 +0100
commit372f8da38bc4b10f0f42488fa5b31bb640521779 (patch)
tree6d19c13ce65573a4a69a78caf4a813cb884d6dce /src
parent8f489b06ba38e6a2df613ec24decaaf0b3af9ffb (diff)
downloadlibsolv-372f8da38bc4b10f0f42488fa5b31bb640521779.tar.gz
libsolv-372f8da38bc4b10f0f42488fa5b31bb640521779.tar.bz2
libsolv-372f8da38bc4b10f0f42488fa5b31bb640521779.zip
implement complex deps handling in cleandeps/unneeded calculation
Diffstat (limited to 'src')
-rw-r--r--src/rules.c223
1 files changed, 186 insertions, 37 deletions
diff --git a/src/rules.c b/src/rules.c
index 9139812..2be3027 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -3331,6 +3331,97 @@ queue_contains(Queue *q, Id id)
return 0;
}
+#ifdef ENABLE_COMPLEX_DEPS
+static void
+complex_cleandeps_remove(Pool *pool, Id ip, Id req, Map *im, Map *installedm, Queue *iq)
+{
+ int i;
+ Queue dq;
+ Id p;
+
+ queue_init(&dq);
+ i = pool_normalize_complex_dep(pool, req, &dq, CPLXDEPS_EXPAND);
+ if (i == 0 || i == 1)
+ {
+ queue_free(&dq);
+ return;
+ }
+ for (i = 0; i < dq.count; i++)
+ {
+ for (; (p = dq.elements[i]) != 0; i++)
+ {
+ if (p < 0)
+ {
+ if (!MAPTST(installedm, -p))
+ break;
+ continue;
+ }
+ if (p != SYSTEMSOLVABLE && MAPTST(im, p))
+ {
+#ifdef CLEANDEPSDEBUG
+ printf("%s requires/recommends %s\n", pool_solvid2str(pool, ip), pool_solvid2str(pool, p));
+#endif
+ queue_push(iq, p);
+ }
+ }
+ while (dq.elements[i])
+ i++;
+ }
+ queue_free(&dq);
+}
+
+static void
+complex_cleandeps_addback(Pool *pool, Id ip, Id req, Map *im, Map *installedm, Queue *iq, Map *userinstalled)
+{
+ int i, blk;
+ Queue dq;
+ Id p;
+
+ queue_init(&dq);
+ i = pool_normalize_complex_dep(pool, req, &dq, CPLXDEPS_EXPAND);
+ if (i == 0 || i == 1)
+ {
+ queue_free(&dq);
+ return;
+ }
+ for (i = 0; i < dq.count; i++)
+ {
+ blk = i;
+ for (; (p = dq.elements[i]) != 0; i++)
+ {
+ if (p < 0)
+ {
+ if (!MAPTST(installedm, -p))
+ break;
+ continue;
+ }
+ if (MAPTST(im, p))
+ break;
+ }
+ if (!p)
+ {
+ for (i = blk; (p = dq.elements[i]) != 0; i++)
+ {
+ if (p < 0)
+ continue;
+ if (!MAPTST(installedm, p))
+ continue;
+ if (p == ip || MAPTST(userinstalled, p - pool->installed->start))
+ continue;
+#ifdef CLEANDEPSDEBUG
+ printf("%s requires/recommends %s\n", pool_solvid2str(pool, ip), pool_solvid2str(pool, p));
+#endif
+ MAPSET(im, p);
+ queue_push(iq, p);
+ }
+ }
+ while (dq.elements[i])
+ i++;
+ }
+ queue_free(&dq);
+}
+
+#endif
/*
* Find all installed packages that are no longer
@@ -3685,14 +3776,12 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
{
if (req == SOLVABLE_PREREQMARKER)
continue;
-#if 0
- /* count number of installed packages that match */
- count = 0;
- FOR_PROVIDES(p, pp, req)
- if (MAPTST(&installedm, p))
- count++;
- if (count > 1)
- continue;
+#ifdef ENABLE_COMPLEX_DEPS
+ if (pool_is_complex_dep(pool, req))
+ {
+ complex_cleandeps_remove(pool, ip, req, &im, &installedm, &iq);
+ continue;
+ }
#endif
FOR_PROVIDES(p, pp, req)
{
@@ -3711,13 +3800,12 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
reqp = s->repo->idarraydata + s->recommends;
while ((req = *reqp++) != 0)
{
-#if 0
- count = 0;
- FOR_PROVIDES(p, pp, req)
- if (MAPTST(&installedm, p))
- count++;
- if (count > 1)
- continue;
+#ifdef ENABLE_COMPLEX_DEPS
+ if (pool_is_complex_dep(pool, req))
+ {
+ complex_cleandeps_remove(pool, ip, req, &im, &installedm, &iq);
+ continue;
+ }
#endif
FOR_PROVIDES(p, pp, req)
{
@@ -3826,6 +3914,13 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
reqp = s->repo->idarraydata + s->requires;
while ((req = *reqp++) != 0)
{
+#ifdef ENABLE_COMPLEX_DEPS
+ if (pool_is_complex_dep(pool, req))
+ {
+ complex_cleandeps_addback(pool, ip, req, &im, &installedm, &iq, &userinstalled);
+ continue;
+ }
+#endif
FOR_PROVIDES(p, pp, req)
if (MAPTST(&im, p))
break;
@@ -3833,7 +3928,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
continue;
FOR_PROVIDES(p, pp, req)
{
- if (!MAPTST(&im, p) && MAPTST(&installedm, p))
+ if (MAPTST(&installedm, p))
{
if (p == ip)
continue;
@@ -3853,6 +3948,13 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
reqp = s->repo->idarraydata + s->recommends;
while ((req = *reqp++) != 0)
{
+#ifdef ENABLE_COMPLEX_DEPS
+ if (pool_is_complex_dep(pool, req))
+ {
+ complex_cleandeps_addback(pool, ip, req, &im, &installedm, &iq, &userinstalled);
+ continue;
+ }
+#endif
FOR_PROVIDES(p, pp, req)
if (MAPTST(&im, p))
break;
@@ -3860,7 +3962,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
continue;
FOR_PROVIDES(p, pp, req)
{
- if (!MAPTST(&im, p) && MAPTST(&installedm, p))
+ if (MAPTST(&installedm, p))
{
if (p == ip)
continue;
@@ -3963,6 +4065,47 @@ trj_visit(struct trj_data *trj, Id node)
}
}
+#ifdef ENABLE_COMPLEX_DEPS
+static void
+complex_unneeded(Pool *pool, Id ip, Id req, Queue *edges, Map *cleandepsmap, Queue *unneededq)
+{
+ int i, j;
+ Queue dq;
+ Id p;
+
+ queue_init(&dq);
+ i = pool_normalize_complex_dep(pool, req, &dq, CPLXDEPS_EXPAND);
+ if (i == 0 || i == 1)
+ {
+ queue_free(&dq);
+ return;
+ }
+ for (i = 0; i < dq.count; i++)
+ {
+ for (; (p = dq.elements[i]) != 0; i++)
+ {
+ if (p < 0)
+ {
+ if (pool->solvables[-p].repo != pool->installed)
+ break;
+ continue;
+ }
+ if (p == ip || pool->solvables[p].repo != pool->installed || !MAPTST(cleandepsmap, p - pool->installed->start))
+ continue;
+ for (j = 0; j < unneededq->count; j++)
+ if (p == unneededq->elements[j])
+ {
+ if (edges->elements[edges->count - 1] != j + 1)
+ queue_push(edges, j + 1);
+ break;
+ }
+ }
+ while (dq.elements[i])
+ i++;
+ }
+ queue_free(&dq);
+}
+#endif
void
solver_get_unneeded(Solver *solv, Queue *unneededq, int filtered)
@@ -4016,31 +4159,37 @@ solver_get_unneeded(Solver *solv, Queue *unneededq, int filtered)
for (i = 0; i < count; i++)
{
Solvable *s = pool->solvables + unneededq->elements[i];
- edges.elements[i + 1] = edges.count;
+ int oldcount = edges.count;
+ edges.elements[i + 1] = oldcount;
for (pass = 0; pass < 2; pass++)
{
- int num = 0;
unsigned int off = pass == 0 ? s->requires : s->recommends;
- Id p, pp, *dp;
+ Id p, pp, dep, *dp;
if (off)
- for (dp = s->repo->idarraydata + off; *dp; dp++)
- FOR_PROVIDES(p, pp, *dp)
- {
- Solvable *sp = pool->solvables + p;
- if (s == sp || sp->repo != installed || !MAPTST(&cleandepsmap, p - installed->start))
- continue;
- for (j = 0; j < count; j++)
- if (p == unneededq->elements[j])
- break;
- if (j == count)
- continue;
- if (num && edges.elements[edges.count - 1] == j + 1)
+ for (dp = s->repo->idarraydata + off; (dep = *dp) != 0; dp++)
+ {
+#ifdef ENABLE_COMPLEX_DEPS
+ if (pool_is_complex_dep(pool, dep))
+ {
+ complex_unneeded(pool, s - pool->solvables, dep, &edges, &cleandepsmap, unneededq);
continue;
- queue_push(&edges, j + 1);
- num++;
- }
- if (pass == 0)
- nrequires[i] = num;
+ }
+#endif
+ FOR_PROVIDES(p, pp, dep)
+ {
+ Solvable *sp = pool->solvables + p;
+ if (s == sp || sp->repo != installed || !MAPTST(&cleandepsmap, p - installed->start))
+ continue;
+ for (j = 0; j < count; j++)
+ if (p == unneededq->elements[j])
+ {
+ if (edges.elements[edges.count - 1] != j + 1)
+ queue_push(&edges, j + 1);
+ }
+ }
+ }
+ if (pass == 0)
+ nrequires[i] = edges.count - oldcount;
}
queue_push(&edges, 0);
}