return 1;
}
-static int
-myrepodatafilter(Repo *repo, Repokey *key, void *kfdata)
-{
- Repodata *data = kfdata;
-
- /* XXX: special repodata selection hack */
- if (key->name == 1 && key->size != data - repo->repodata)
- return -1;
- if (key->storage == KEY_STORAGE_SOLVABLE)
- return KEY_STORAGE_DROPPED;
- return repo_write_stdkeyfilter(repo, key, kfdata);
-}
-
void
writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char *cookie)
{
char *tmpl;
int myinfo = 0;
struct repoinfo *cinfo;
+ int onepiece;
cinfo = repo->appdata;
mkdir(SOLVCACHE_PATH, 0755);
free(tmpl);
return;
}
+
+ onepiece = 1;
+ for (i = repo->start; i < repo->end; i++)
+ if (repo->pool->solvables[i].repo != repo)
+ break;
+ if (i < repo->end)
+ onepiece = 0;
+
if (!repoext)
{
if (!info)
repo_write(repo, fp, repo_write_stdkeyfilter, 0, 0);
}
else
- repo_write(repo, fp, myrepodatafilter, info, 0);
+ repodata_write(info, fp, repo_write_stdkeyfilter, 0);
if (myinfo)
repodata_free(info);
if (fwrite(cookie, 32, 1, fp) != 1)
if (!stat(tmpl, &stb))
calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, cinfo->extcookie);
}
+ if (onepiece)
+ {
+ /* switch to just saved repo to activate paging and save memory */
+ FILE *fp = fopen(tmpl, "r");
+ if (fp)
+ {
+ if (!repoext)
+ {
+ /* main repo */
+ repo_empty(repo, 1);
+ if (repo_add_solv(repo, fp))
+ {
+ /* oops, no way to recover from here */
+ fprintf(stderr, "internal error\n");
+ exit(1);
+ }
+ }
+ else
+ {
+ /* make sure repodata contains complete repo */
+ /* (this is how repodata_write saves it) */
+ repodata_extend_block(info, repo->start, repo->end - repo->start);
+ info->state = REPODATA_LOADING;
+ /* no need for LOCALPOOL as pool already contains ids */
+ repo_add_solv_flags(repo, fp, REPO_USE_LOADING|REPO_EXTEND_SOLVABLES);
+ info->state = REPODATA_AVAILABLE; /* in case the load failed */
+ }
+ fclose(fp);
+ }
+ }
if (!rename(tmpl, calccachepath(repo, repoext)))
unlink(tmpl);
free(tmpl);
sat_free(repodataused);
sat_free(repodataschemata);
}
+
+struct repodata_write_data {
+ int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata);
+ void *kfdata;
+ int repodataid;
+};
+
+static int
+repodata_write_keyfilter(Repo *repo, Repokey *key, void *kfdata)
+{
+ struct repodata_write_data *wd = kfdata;
+
+ /* XXX: special repodata selection hack */
+ if (key->name == 1 && key->size != wd->repodataid)
+ return -1;
+ if (key->storage == KEY_STORAGE_SOLVABLE)
+ return KEY_STORAGE_DROPPED; /* not part of this repodata */
+ if (wd->keyfilter)
+ return (*wd->keyfilter)(repo, key, wd->kfdata);
+ return key->storage;
+}
+
+void
+repodata_write(Repodata *data, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata)
+{
+ struct repodata_write_data wd;
+
+ wd.keyfilter = keyfilter;
+ wd.kfdata = kfdata;
+ wd.repodataid = data - data->repo->repodata;
+ repo_write(data->repo, fp, repodata_write_keyfilter, &wd, 0);
+}
void repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Id **keyarrayp);
int repo_write_stdkeyfilter(Repo *repo, Repokey *key, void *kfdata);
+void repodata_write(Repodata *data , FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata);
+
#endif
sat_free(repo);
}
-/*
- * remove repo from pool, zero out (i.e. free) solvables
- *
- */
+/* delete all solvables and repodata blocks from this repo */
void
-repo_free(Repo *repo, int reuseids)
+repo_empty(Repo *repo, int reuseids)
{
Pool *pool = repo->pool;
Solvable *s;
for (i = repo->end - 1, s = pool->solvables + i; i >= repo->start; i--, s--)
if (s->repo != repo)
break;
- repo->end = i + 1;
- pool->nsolvables = i + 1;
+ pool_free_solvable_block(pool, i + 1, repo->end - (i + 1), reuseids);
}
/* zero out (i.e. free) solvables belonging to this repo */
for (i = repo->start, s = pool->solvables + i; i < repo->end; i++, s++)
if (s->repo == repo)
memset(s, 0, sizeof(*s));
+ repo->nsolvables = 0;
+
+ /* free all data belonging to this repo */
+ repo->idarraydata = sat_free(repo->idarraydata);
+ repo->idarraysize = 0;
+ repo->lastoff = 0;
+ repo->rpmdbid = sat_free(repo->rpmdbid);
+ for (i = 0; i < repo->nrepodata; i++)
+ repodata_freedata(repo->repodata + i);
+ repo->repodata = 0;
+ repo->nrepodata = 0;
+}
+
+/*
+ * remove repo from pool, delete solvables
+ *
+ */
+
+void
+repo_free(Repo *repo, int reuseids)
+{
+ Pool *pool = repo->pool;
+ int i;
+
+ repo_empty(repo, reuseids);
for (i = 0; i < pool->nrepos; i++) /* find repo in pool */
if (pool->repos[i] == repo)
break;
typedef struct _Repo {
- const char *name; /* application private name pointer */
+ const char *name; /* name pointer */
Id repoid; /* our id */
void *appdata; /* application private pointer */
extern Repo *repo_create(Pool *pool, const char *name);
extern void repo_free(Repo *repo, int reuseids);
+extern void repo_empty(Repo *repo, int reuseids);
extern void repo_freeallrepos(Pool *pool, int reuseids);
extern void repo_free_solvable_block(Repo *repo, Id start, int count, int reuseids);
extern void *repo_sidedata_create(Repo *repo, size_t size);
int i = data - repo->repodata;
repodata_freedata(data);
if (i < repo->nrepodata - 1)
- memmove(repo->repodata + i, repo->repodata + i + 1, (repo->nrepodata - 1 - i) * sizeof(Repodata));
+ memmove(repo->repodata + i, repo->repodata + i + 1, (repo->nrepodata - 1 - i) * sizeof(Repodata));
repo->nrepodata--;
}