-/*******************************************************************/
-
-struct mptree {
- Id sibling;
- Id child;
- const char *comp;
- int compl;
- Id mountpoint;
-};
-
-struct ducbdata {
- DUChanges *mps;
- struct mptree *mptree;
- int addsub;
- int hasdu;
-
- Id *dirmap;
- int nmap;
- Repodata *olddata;
-};
-
-
-static int
-solver_fill_DU_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *value)
-{
- struct ducbdata *cbd = cbdata;
- Id mp;
-
- if (data != cbd->olddata)
- {
- Id dn, mp, comp, *dirmap, *dirs;
- int i, compl;
- const char *compstr;
- struct mptree *mptree;
-
- /* create map from dir to mptree */
- cbd->dirmap = sat_free(cbd->dirmap);
- cbd->nmap = 0;
- dirmap = sat_calloc(data->dirpool.ndirs, sizeof(Id));
- mptree = cbd->mptree;
- mp = 0;
- for (dn = 2, dirs = data->dirpool.dirs + dn; dn < data->dirpool.ndirs; dn++)
- {
- comp = *dirs++;
- if (comp <= 0)
- {
- mp = dirmap[-comp];
- continue;
- }
- if (mp < 0)
- {
- /* unconnected */
- dirmap[dn] = mp;
- continue;
- }
- if (!mptree[mp].child)
- {
- dirmap[dn] = -mp;
- continue;
- }
- if (data->localpool)
- compstr = stringpool_id2str(&data->spool, comp);
- else
- compstr = id2str(data->repo->pool, comp);
- compl = strlen(compstr);
- for (i = mptree[mp].child; i; i = mptree[i].sibling)
- if (mptree[i].compl == compl && !strncmp(mptree[i].comp, compstr, compl))
- break;
- dirmap[dn] = i ? i : -mp;
- }
- /* change dirmap to point to mountpoint instead of mptree */
- for (dn = 0; dn < data->dirpool.ndirs; dn++)
- {
- mp = dirmap[dn];
- dirmap[dn] = mptree[mp > 0 ? mp : -mp].mountpoint;
- }
- cbd->dirmap = dirmap;
- cbd->nmap = data->dirpool.ndirs;
- cbd->olddata = data;
- }
- cbd->hasdu = 1;
- if (value->id < 0 || value->id >= cbd->nmap)
- return 0;
- mp = cbd->dirmap[value->id];
- if (mp < 0)
- return 0;
- if (cbd->addsub > 0)
- {
- cbd->mps[mp].kbytes += value->num;
- cbd->mps[mp].files += value->num2;
- }
- else
- {
- cbd->mps[mp].kbytes -= value->num;
- cbd->mps[mp].files -= value->num2;
- }
- return 0;
-}
-
-static void
-propagate_mountpoints(struct mptree *mptree, int pos, Id mountpoint)
-{
- int i;
- if (mptree[pos].mountpoint == -1)
- mptree[pos].mountpoint = mountpoint;
- else
- mountpoint = mptree[pos].mountpoint;
- for (i = mptree[pos].child; i; i = mptree[i].sibling)
- propagate_mountpoints(mptree, i, mountpoint);
-}
-
-#define MPTREE_BLOCK 15
-
-void
-pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps)
-{
- char *p;
- const char *path, *compstr;
- struct mptree *mptree;
- int i, nmptree;
- int pos, compl;
- int mp;
- struct ducbdata cbd;
- Solvable *s;
- Id sp;
- Map ignoredu;
- Repo *oldinstalled = pool->installed;
-
- memset(&ignoredu, 0, sizeof(ignoredu));
- cbd.mps = mps;
- cbd.addsub = 0;
- cbd.dirmap = 0;
- cbd.nmap = 0;
- cbd.olddata = 0;
-
- mptree = sat_extend_resize(0, 1, sizeof(struct mptree), MPTREE_BLOCK);
-
- /* our root node */
- mptree[0].sibling = 0;
- mptree[0].child = 0;
- mptree[0].comp = 0;
- mptree[0].compl = 0;
- mptree[0].mountpoint = -1;
- nmptree = 1;
-
- /* create component tree */
- for (mp = 0; mp < nmps; mp++)
- {
- mps[mp].kbytes = 0;
- mps[mp].files = 0;
- pos = 0;
- path = mps[mp].path;
- while(*path == '/')
- path++;
- while (*path)
- {
- if ((p = strchr(path, '/')) == 0)
- {
- compstr = path;
- compl = strlen(compstr);
- path += compl;
- }
- else
- {
- compstr = path;
- compl = p - path;
- path = p + 1;
- while(*path == '/')
- path++;
- }
- for (i = mptree[pos].child; i; i = mptree[i].sibling)
- if (mptree[i].compl == compl && !strncmp(mptree[i].comp, compstr, compl))
- break;
- if (!i)
- {
- /* create new node */
- mptree = sat_extend(mptree, nmptree, 1, sizeof(struct mptree), MPTREE_BLOCK);
- i = nmptree++;
- mptree[i].sibling = mptree[pos].child;
- mptree[i].child = 0;
- mptree[i].comp = compstr;
- mptree[i].compl = compl;
- mptree[i].mountpoint = -1;
- mptree[pos].child = i;
- }
- pos = i;
- }
- mptree[pos].mountpoint = mp;
- }
-
- propagate_mountpoints(mptree, 0, mptree[0].mountpoint);
-
-#if 0
- for (i = 0; i < nmptree; i++)
- {
- printf("#%d sibling: %d\n", i, mptree[i].sibling);
- printf("#%d child: %d\n", i, mptree[i].child);
- printf("#%d comp: %s\n", i, mptree[i].comp);
- printf("#%d compl: %d\n", i, mptree[i].compl);
- printf("#%d mountpont: %d\n", i, mptree[i].mountpoint);
- }
-#endif
-
- cbd.mptree = mptree;
- cbd.addsub = 1;
- for (sp = 1, s = pool->solvables + sp; sp < pool->nsolvables; sp++, s++)
- {
- if (!s->repo || (oldinstalled && s->repo == oldinstalled))
- continue;
- if (!MAPTST(installedmap, sp))
- continue;
- cbd.hasdu = 0;
- repo_search(s->repo, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
- if (!cbd.hasdu && oldinstalled)
- {
- Id op, opp;
- /* no du data available, ignore data of all installed solvables we obsolete */
- if (!ignoredu.map)
- map_init(&ignoredu, oldinstalled->end - oldinstalled->start);
- if (s->obsoletes)
- {
- Id obs, *obsp = s->repo->idarraydata + s->obsoletes;
- while ((obs = *obsp++) != 0)
- FOR_PROVIDES(op, opp, obs)
- if (op >= oldinstalled->start && op < oldinstalled->end)
- MAPSET(&ignoredu, op - oldinstalled->start);
- }
- FOR_PROVIDES(op, opp, s->name)
- if (pool->solvables[op].name == s->name)
- if (op >= oldinstalled->start && op < oldinstalled->end)
- MAPSET(&ignoredu, op - oldinstalled->start);
- }
- }
- cbd.addsub = -1;
- if (oldinstalled)
- {
- /* assumes we allways have du data for installed solvables */
- FOR_REPO_SOLVABLES(oldinstalled, sp, s)
- {
- if (MAPTST(installedmap, sp))
- continue;
- if (ignoredu.map && MAPTST(&ignoredu, sp - oldinstalled->start))
- continue;
- repo_search(oldinstalled, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
- }
- }
- if (ignoredu.map)
- map_free(&ignoredu);
- sat_free(cbd.dirmap);
- sat_free(mptree);
-}
-
-int
-pool_calc_installsizechange(Pool *pool, Map *installedmap)
-{
- Id sp;
- Solvable *s;
- int change = 0;
- Repo *oldinstalled = pool->installed;
-
- for (sp = 1, s = pool->solvables + sp; sp < pool->nsolvables; sp++, s++)
- {
- if (!s->repo || (oldinstalled && s->repo == oldinstalled))
- continue;
- if (!MAPTST(installedmap, sp))
- continue;
- change += solvable_lookup_num(s, SOLVABLE_INSTALLSIZE, 0);
- }
- if (oldinstalled)
- {
- FOR_REPO_SOLVABLES(oldinstalled, sp, s)
- {
- if (MAPTST(installedmap, sp))
- continue;
- change -= solvable_lookup_num(s, SOLVABLE_INSTALLSIZE, 0);
- }
- }
- return change;
-}
-