2 * Copyright (c) 2007-2016, SUSE LLC
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
11 * calculate needed space on partitions
37 struct mptree *mptree;
48 solver_fill_DU_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *value)
50 struct ducbdata *cbd = cbdata;
53 if (data != cbd->olddata)
55 Id dn, mp, comp, *dirmap, *dirs;
58 struct mptree *mptree;
60 /* create map from dir to mptree */
61 cbd->dirmap = solv_free(cbd->dirmap);
63 dirmap = solv_calloc(data->dirpool.ndirs, sizeof(Id));
66 for (dn = 2, dirs = data->dirpool.dirs + dn; dn < data->dirpool.ndirs; dn++)
80 if (!mptree[mp].child)
86 compstr = stringpool_id2str(&data->spool, comp);
88 compstr = pool_id2str(data->repo->pool, comp);
89 compl = strlen(compstr);
90 for (i = mptree[mp].child; i; i = mptree[i].sibling)
91 if (mptree[i].compl == compl && !strncmp(mptree[i].comp, compstr, compl))
93 dirmap[dn] = i ? i : -mp;
95 /* change dirmap to point to mountpoint instead of mptree */
96 for (dn = 0; dn < data->dirpool.ndirs; dn++)
99 dirmap[dn] = mptree[mp > 0 ? mp : -mp].mountpoint;
101 cbd->dirmap = dirmap;
102 cbd->nmap = data->dirpool.ndirs;
106 if (value->id < 0 || value->id >= cbd->nmap)
108 mp = cbd->dirmap[value->id];
113 cbd->mps[mp].kbytes += value->num;
114 cbd->mps[mp].files += value->num2;
116 else if (!(cbd->mps[mp].flags & DUCHANGES_ONLYADD))
118 cbd->mps[mp].kbytes -= value->num;
119 cbd->mps[mp].files -= value->num2;
125 propagate_mountpoints(struct mptree *mptree, int pos, Id mountpoint)
128 if (mptree[pos].mountpoint == -1)
129 mptree[pos].mountpoint = mountpoint;
131 mountpoint = mptree[pos].mountpoint;
132 for (i = mptree[pos].child; i; i = mptree[i].sibling)
133 propagate_mountpoints(mptree, i, mountpoint);
136 #define MPTREE_BLOCK 15
138 static struct mptree *
139 create_mptree(DUChanges *mps, int nmps)
142 struct mptree *mptree;
145 const char *p, *path, *compstr;
147 mptree = solv_extend_resize(0, 1, sizeof(struct mptree), MPTREE_BLOCK);
150 mptree[0].sibling = 0;
154 mptree[0].mountpoint = -1;
157 /* create component tree */
158 for (mp = 0; mp < nmps; mp++)
168 if ((p = strchr(path, '/')) == 0)
171 compl = strlen(compstr);
182 for (i = mptree[pos].child; i; i = mptree[i].sibling)
183 if (mptree[i].compl == compl && !strncmp(mptree[i].comp, compstr, compl))
187 /* create new node */
188 mptree = solv_extend(mptree, nmptree, 1, sizeof(struct mptree), MPTREE_BLOCK);
190 mptree[i].sibling = mptree[pos].child;
192 mptree[i].comp = compstr;
193 mptree[i].compl = compl;
194 mptree[i].mountpoint = -1;
195 mptree[pos].child = i;
199 mptree[pos].mountpoint = mp;
202 propagate_mountpoints(mptree, 0, mptree[0].mountpoint);
205 for (i = 0; i < nmptree; i++)
207 printf("#%d sibling: %d\n", i, mptree[i].sibling);
208 printf("#%d child: %d\n", i, mptree[i].child);
209 printf("#%d comp: %s\n", i, mptree[i].comp);
210 printf("#%d compl: %d\n", i, mptree[i].compl);
211 printf("#%d mountpont: %d\n", i, mptree[i].mountpoint);
219 pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps)
221 struct mptree *mptree;
226 Repo *oldinstalled = pool->installed;
229 map_init(&ignoredu, 0);
230 mptree = create_mptree(mps, nmps);
232 for (i = 0; i < nmps; i++)
233 if ((mps[i].flags & DUCHANGES_ONLYADD) != 0)
241 for (sp = 1, s = pool->solvables + sp; sp < pool->nsolvables; sp++, s++)
243 if (!s->repo || (oldinstalled && s->repo == oldinstalled))
245 if (!MAPTST(installedmap, sp))
248 repo_search(s->repo, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
249 if (!cbd.hasdu && oldinstalled)
253 /* no du data available, ignore data of all installed solvables we obsolete */
255 map_grow(&ignoredu, oldinstalled->end - oldinstalled->start);
256 FOR_PROVIDES(op, opp, s->name)
258 Solvable *s2 = pool->solvables + op;
259 if (!pool->implicitobsoleteusesprovides && s->name != s2->name)
261 if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, s2))
263 if (op >= oldinstalled->start && op < oldinstalled->end)
265 MAPSET(&ignoredu, op - oldinstalled->start);
266 if (haveonlyadd && pool->solvables[op].repo == oldinstalled && !didonlyadd)
268 repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
270 repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
278 Id obs, *obsp = s->repo->idarraydata + s->obsoletes;
279 while ((obs = *obsp++) != 0)
280 FOR_PROVIDES(op, opp, obs)
282 Solvable *s2 = pool->solvables + op;
283 if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, s2, obs))
285 if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2))
287 if (op >= oldinstalled->start && op < oldinstalled->end)
289 MAPSET(&ignoredu, op - oldinstalled->start);
290 if (haveonlyadd && pool->solvables[op].repo == oldinstalled && !didonlyadd)
292 repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
294 repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
306 /* assumes we allways have du data for installed solvables */
307 FOR_REPO_SOLVABLES(oldinstalled, sp, s)
309 if (MAPTST(installedmap, sp))
311 if (ignoredu.size && MAPTST(&ignoredu, sp - oldinstalled->start))
313 repo_search(oldinstalled, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
317 solv_free(cbd.dirmap);
322 pool_calc_installsizechange(Pool *pool, Map *installedmap)
326 long long change = 0;
327 Repo *oldinstalled = pool->installed;
329 for (sp = 1, s = pool->solvables + sp; sp < pool->nsolvables; sp++, s++)
331 if (!s->repo || (oldinstalled && s->repo == oldinstalled))
333 if (!MAPTST(installedmap, sp))
335 change += solvable_lookup_sizek(s, SOLVABLE_INSTALLSIZE, 0);
339 FOR_REPO_SOLVABLES(oldinstalled, sp, s)
341 if (MAPTST(installedmap, sp))
343 change -= solvable_lookup_sizek(s, SOLVABLE_INSTALLSIZE, 0);