- add repodata_write and repo_empty functions
authorMichael Schroeder <mls@suse.de>
Fri, 17 Jul 2009 09:20:19 +0000 (11:20 +0200)
committerMichael Schroeder <mls@suse.de>
Fri, 17 Jul 2009 09:20:19 +0000 (11:20 +0200)
- make solv tool switch to written solv files to activate paging

examples/solv.c
ext/repo_write.c
ext/repo_write.h
src/repo.c
src/repo.h
src/repodata.c

index a7ce9b8..5a6c8ea 100644 (file)
@@ -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);
index c17ead4..33cdfd2 100644 (file)
@@ -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);
+}
index 5fc9bf2..87a79d4 100644 (file)
@@ -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
index 0897b77..44d8790 100644 (file)
@@ -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;
index b66631b..3d16151 100644 (file)
@@ -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);
index e256245..6a3194a 100644 (file)
@@ -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--;
 }