ref: refs/heads/master
commit c3dbfd88dc0cb788e8e1c1e950714d3bd82f9415
Author: Michael Schroeder
Date: Fri Jul 17 11:20:19 2009 +0200
- add repodata_write and repo_empty functions
- make solv tool switch to written solv files to activate paging
---
examples/solv.c | 54 ++++++++++++++++++++++++++++++++++++++++--------------
ext/repo_write.c | 32 ++++++++++++++++++++++++++++++++
ext/repo_write.h | 2 ++
src/repo.c | 35 ++++++++++++++++++++++++++++-------
src/repo.h | 3 ++-
src/repodata.c | 2 +-
6 files changed, 105 insertions(+), 23 deletions(-)
diff --git a/examples/solv.c b/examples/solv.c
index a7ce9b8..5a6c8ea 100644
--- a/examples/solv.c
+++ b/examples/solv.c
@@ -646,19 +646,6 @@ usecachedrepo(Repo *repo, const char *repoext, unsigned char *cookie)
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)
{
@@ -668,6 +655,7 @@ writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char *
char *tmpl;
int myinfo = 0;
struct repoinfo *cinfo;
+ int onepiece;
cinfo = repo->appdata;
mkdir(SOLVCACHE_PATH, 0755);
@@ -686,6 +674,14 @@ writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char *
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)
@@ -704,7 +700,7 @@ writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char *
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)
@@ -727,6 +723,36 @@ writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char *
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);
diff --git a/ext/repo_write.c b/ext/repo_write.c
index c17ead4..33cdfd2 100644
--- a/ext/repo_write.c
+++ b/ext/repo_write.c
@@ -1994,3 +1994,35 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
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);
+}
diff --git a/ext/repo_write.h b/ext/repo_write.h
index 5fc9bf2..87a79d4 100644
--- a/ext/repo_write.h
+++ b/ext/repo_write.h
@@ -20,4 +20,6 @@
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
diff --git a/src/repo.c b/src/repo.c
index 0897b77..44d8790 100644
--- a/src/repo.c
+++ b/src/repo.c
@@ -68,13 +68,10 @@ repo_freedata(Repo *repo)
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;
@@ -91,13 +88,37 @@ repo_free(Repo *repo, int reuseids)
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;
diff --git a/src/repo.h b/src/repo.h
index b66631b..3d16151 100644
--- a/src/repo.h
+++ b/src/repo.h
@@ -20,7 +20,7 @@
typedef struct _Repo {
- const char *name; /* application private name pointer */
+ const char *name; /* name pointer */
Id repoid; /* our id */
void *appdata; /* application private pointer */
@@ -46,6 +46,7 @@ typedef struct _Repo {
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);
diff --git a/src/repodata.c b/src/repodata.c
index e256245..6a3194a 100644
--- a/src/repodata.c
+++ b/src/repodata.c
@@ -116,7 +116,7 @@ repodata_free(Repodata *data)
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--;
}
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org