- add solvable allocation functions
authorMichael Schroeder <mls@suse.de>
Fri, 16 Nov 2007 20:11:07 +0000 (20:11 +0000)
committerMichael Schroeder <mls@suse.de>
Fri, 16 Nov 2007 20:11:07 +0000 (20:11 +0000)
- fix bug in rpmid handling

12 files changed:
src/pool.c
src/pool.h
src/repo.c
src/repo.h
src/repo_solv.c
tools/repo_content.c
tools/repo_helix.c
tools/repo_patchxml.c
tools/repo_rpmdb.c
tools/repo_rpmmd.c
tools/repo_susetags.c
tools/repo_write.c

index c40d337..2e79b43 100644 (file)
@@ -24,6 +24,7 @@
 #include "util.h"
 #include "evr.h"
 
+#define SOLVABLE_BLOCK 255
 
 // reset all whatprovides
 // 
@@ -85,7 +86,7 @@ pool_create(void)
   pool->nrels = 1;
 
   // pre-alloc space for a Solvable
-  pool->solvables = (Solvable *)xcalloc(2, sizeof(Solvable));
+  pool->solvables = (Solvable *)xcalloc(SOLVABLE_BLOCK + 1, sizeof(Solvable));
   pool->nsolvables = 2;
   queue_init(&pool->vendormap);
   s = pool->solvables + SYSTEMSOLVABLE;
@@ -117,6 +118,41 @@ pool_free(Pool *pool)
   xfree(pool);
 }
 
+Id
+pool_add_solvable(Pool *pool)
+{
+  if ((pool->nsolvables & SOLVABLE_BLOCK) == 0)
+    pool->solvables = xrealloc2(pool->solvables, pool->nsolvables + (SOLVABLE_BLOCK + 1), sizeof(Solvable));
+  memset(pool->solvables + pool->nsolvables, 0, sizeof(Solvable));
+  return pool->nsolvables++;
+}
+
+Id
+pool_add_solvable_block(Pool *pool, int count)
+{
+  Id nsolvables = pool->nsolvables;
+  if (!count)
+    return nsolvables;
+  if (((nsolvables - 1) | SOLVABLE_BLOCK) != ((nsolvables + count - 1) | SOLVABLE_BLOCK))
+    pool->solvables = xrealloc2(pool->solvables, (nsolvables + count + SOLVABLE_BLOCK) & ~SOLVABLE_BLOCK, sizeof(Solvable));
+  memset(pool->solvables + nsolvables, 0, sizeof(Solvable) * count);
+  pool->nsolvables += count;
+  return nsolvables;
+}
+
+void
+pool_free_solvable_block(Pool *pool, Id start, int count, int reuseids)
+{
+  if (!count)
+    return;
+  if (reuseids && start + count == pool->nsolvables)
+    {
+      /* might want to shrink solvable array */
+      pool->nsolvables = start;
+      return;
+    }
+  memset(pool->solvables + start, 0, sizeof(Solvable) * count);
+}
 
 static Pool *pool_shrink_whatprovides_sortcmp_data;
 
index aa019a3..84a40eb 100644 (file)
@@ -149,6 +149,12 @@ extern Pool *pool_create(void);
  * Delete a pool
  */
 extern void pool_free(Pool *pool);
+
+extern Id pool_add_solvable(Pool *pool);
+extern Id pool_add_solvable_block(Pool *pool, int count);
+
+extern void pool_free_solvable_block(Pool *pool, Id start, int count, int reuseids);
+
 /**
  * Prepares a pool for solving
  */
index 8e05b66..9f00727 100644 (file)
@@ -293,13 +293,10 @@ pool_freeallrepos(Pool *pool, int reuseids)
   pool_freewhatprovides(pool);
   for (i = 0; i < pool->nrepos; i++)
     repo_freedata(pool->repos[i]);
-  /* the first two solvables don't belong to a repo */
-  if (pool->nsolvables > 2 && !reuseids)
-    memset(pool->solvables + 2, 0, (pool->nsolvables - 2) * sizeof(Solvable));
   pool->repos = xfree(pool->repos);
   pool->nrepos = 0;
-  if (reuseids)
-    pool->nsolvables = 2;
+  /* the first two solvables don't belong to a repo */
+  pool_free_solvable_block(pool, 2, pool->nsolvables - 2, reuseids);
 }
 
 Offset
index 1d51f13..381cc73 100644 (file)
@@ -46,4 +46,50 @@ static inline const char *repo_name(const Repo *repo)
   return repo->name;
 }
 
+static inline Id repo_add_solvable(Repo *repo)
+{
+  extern Id pool_add_solvable(Pool *pool);
+  Id p = pool_add_solvable(repo->pool);
+  if (!repo->start || repo->start == repo->end)
+    {
+      repo->start = p;
+      repo->end = p + 1;
+      return p;
+    }
+  if (p < repo->start)
+    repo->start = p;
+  if (p + 1 > repo->end)
+    repo->end = p + 1;
+  return p;
+}
+
+static inline Id repo_add_solvable_block(Repo *repo, int count)
+{
+  extern Id pool_add_solvable_block(Pool *pool, int count);
+  Id p;
+  if (!count)
+    return 0;
+  p = pool_add_solvable_block(repo->pool, count);
+  if (!repo->start || repo->start == repo->end)
+    {
+      repo->start = p;
+      repo->end = p + count;
+      return p;
+    }
+  if (p < repo->start)
+    repo->start = p;
+  if (p + count > repo->end)
+    repo->end = p + count;
+  return p;
+}
+
+/* does not modify repo->nsolvables! */
+static inline void repo_free_solvable_block(Repo *repo, Id start, int count, int reuseids)
+{
+  extern void pool_free_solvable_block(Pool *pool, Id start, int count, int reuseids);
+  if (start + count == repo->end)
+    repo->end -= count;
+  pool_free_solvable_block(repo->pool, start, count, reuseids);
+}
+
 #endif /* REPO_H */
index 6c512e8..a7263ef 100644 (file)
@@ -499,18 +499,6 @@ repo_add_solv(Repo *repo, FILE *fp)
       idarraydataend = 0;
     }
 
-
-  /* alloc space for our solvables */
-  if (numsolv)                        /* clear newly allocated area */
-    {
-      pool->solvables = (Solvable *)xrealloc(pool->solvables, (pool->nsolvables + numsolv) * sizeof(Solvable));
-
-      memset(pool->solvables + pool->nsolvables, 0, numsolv * sizeof(Solvable));
-      if (!repo->start || repo->start == repo->end)
-       repo->start = pool->nsolvables;
-      repo->end = pool->nsolvables;
-    }
-
   /*
    * read solvables
    */
@@ -518,7 +506,9 @@ repo_add_solv(Repo *repo, FILE *fp)
 #if 0
   printf("read solvables\n");
 #endif
-  for (i = 0, s = pool->solvables + pool->nsolvables; i < numsolv; i++, s++)
+  id = repo_add_solvable_block(repo, numsolv);
+  s = pool->solvables + id;
+  for (i = 0; i < numsolv; i++, s++)
     {
       s->repo = repo;
       databits = 0;
@@ -610,13 +600,10 @@ repo_add_solv(Repo *repo, FILE *fp)
            }
        }
     }
+  repo->nsolvables += numsolv;
 
   xfree(idmap);
   xfree(solvdata);
-
-  repo->end += numsolv;
-  repo->nsolvables += numsolv;
-  pool->nsolvables += numsolv;
 }
 
 // EOF
index 7684e82..a6d74d4 100644 (file)
@@ -17,8 +17,6 @@
 #include "util.h"
 #include "repo_content.h"
 
-#define PACK_BLOCK 16
-
 static int
 split(char *l, char **sp, int m)
 {
@@ -167,7 +165,7 @@ repo_add_content(Repo *repo, FILE *fp)
   char *line, *linep;
   int aline;
   Solvable *s;
-  int pack;
+  Id id;
   struct parsedata pd;
 
   memset(&pd, 0, sizeof(pd));
@@ -176,13 +174,8 @@ repo_add_content(Repo *repo, FILE *fp)
 
   pd.repo = repo;
   linep = line;
-  pack = 0;
   s = 0;
 
-  if (!repo->start || repo->start == repo->end)
-    repo->start = pool->nsolvables;
-  repo->end = pool->nsolvables;
-
   for (;;)
     {
       char *fields[2];
@@ -217,21 +210,18 @@ repo_add_content(Repo *repo, FILE *fp)
 #define istag(x) !strcmp (key, x)
          if (istag ("PRODUCT"))
            {
+             /* finish old solvable */
              if (s && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
                s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
              if (s)
                s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);
              /* Only support one product.  */
              pd.kind = "product";
-             if ((pack & PACK_BLOCK) == 0)
-               {
-                 pool->solvables = realloc(pool->solvables, (pool->nsolvables + pack + PACK_BLOCK + 1) * sizeof(Solvable));
-                 memset(pool->solvables + pool->nsolvables + pack, 0, (PACK_BLOCK + 1) * sizeof(Solvable));
-               }
-             s = pool->solvables + pool->nsolvables + pack;
+             id = repo_add_solvable(repo);
+             s = pool->solvables + id;
              s->repo = repo;
+             repo->nsolvables++;
              s->name = str2id(pool, join(&pd, pd.kind, ":", value), 1);
-             pack++;
            }
          else if (istag ("VERSION"))
            /* without a release? but that's like zypp implements it */
@@ -278,9 +268,6 @@ repo_add_content(Repo *repo, FILE *fp)
   if (s)
     s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);
     
-  pool->nsolvables += pack;
-  repo->nsolvables += pack;
-  repo->end += pack;
   if (pd.tmp)
     free(pd.tmp);
   free(line);
index 8038d20..33bce55 100644 (file)
@@ -73,8 +73,6 @@ enum state {
   NUMSTATES
 };
 
-#define PACK_BLOCK 255
-
 struct stateswitch {
   enum state from;
   char *ename;
@@ -142,11 +140,9 @@ typedef struct _parsedata {
   int docontent;       // handle content
 
   // repo data
-  int pack;             // number of solvables
-
   Pool *pool;          // current pool
-  Repo *repo;  // current repo
-  Solvable *start;      // collected solvables
+  Repo *repo;          // current repo
+  Solvable *solvable;  // current solvable
 
   // package data
   int  epoch;          // epoch (as offset into evrspace)
@@ -379,7 +375,8 @@ startElement(void *userData, const char *name, const char **atts)
   Parsedata *pd = (Parsedata *)userData;
   struct stateswitch *sw;
   Pool *pool = pd->pool;
-  Solvable *s = pd->start ? pd->start + pd->pack : 0;
+  Solvable *s = pd->solvable;
+  Id id;
 
   if (pd->depth != pd->statedepth)
     {
@@ -433,20 +430,9 @@ startElement(void *userData, const char *name, const char **atts)
        }
       break;
 
-    case STATE_SUBCHANNEL:
-      pd->pack = 0;
-      break;
-
-
     case STATE_PACKAGE:                       /* solvable name */
-
-      if ((pd->pack & PACK_BLOCK) == 0)  /* alloc new block ? */
-       {
-         pool->solvables = (Solvable *)realloc(pool->solvables, (pool->nsolvables + pd->pack + PACK_BLOCK + 1) * sizeof(Solvable));
-         pd->start = pool->solvables + pool->nsolvables;
-          memset(pd->start + pd->pack, 0, (PACK_BLOCK + 1) * sizeof(Solvable));
-       }
-
+      id = repo_add_solvable(pd->repo);
+      pd->solvable = pool->solvables + id;
       if (!strcmp(name, "selection"))
         pd->kind = "selection";
       else if (!strcmp(name, "pattern"))
@@ -464,7 +450,7 @@ startElement(void *userData, const char *name, const char **atts)
       pd->version = 0;
       pd->release = 0;
 #if 0
-      fprintf(stderr, "package #%d\n", pd->pack);
+      fprintf(stderr, "package #%d\n", id);
 #endif
       break;
 
@@ -558,9 +544,6 @@ static const char* findKernelFlavor(Parsedata *pd, Solvable *s)
        }
     }
 
-  //fprintf(stderr, "pack %d\n", pd->pack);
-  //fprintf(stderr, "repo %d\n", s->requires);
-
   if (!s->requires)
     return 0;
 
@@ -599,7 +582,7 @@ endElement(void *userData, const char *name)
 {
   Parsedata *pd = (Parsedata *)userData;
   Pool *pool = pd->pool;
-  Solvable *s = pd->start ? pd->start + pd->pack : NULL;
+  Solvable *s = pd->solvable;
   Id evr;
 
   if (pd->depth != pd->statedepth)
@@ -620,6 +603,7 @@ endElement(void *userData, const char *name)
 
     case STATE_PACKAGE:                       /* package complete */
       s->repo = pd->repo;
+      pd->repo->nsolvables++;
 
       if (!s->arch)                    /* default to "noarch" */
        s->arch = ARCH_NOARCH;
@@ -718,9 +702,6 @@ endElement(void *userData, const char *name)
 #endif
          free(cflavor);
        }
-
-      pd->pack++;                     /* inc pack count */
-
       break;
     case STATE_NAME:
       s->name = str2id(pool, pd->content, 1);
@@ -826,12 +807,6 @@ repo_add_helix(Repo *repo, FILE *fp)
   int i, l;
   struct stateswitch *sw;
 
-  if (repo->start && repo->start + repo->nsolvables != pool->nsolvables)
-    abort();
-  if (!repo->start || repo->start == repo->end)
-    repo->start = pool->nsolvables;
-  repo->end = pool->nsolvables;
-
   /* prepare parsedata */
   memset(&pd, 0, sizeof(pd));
   for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
@@ -873,11 +848,6 @@ repo_add_helix(Repo *repo, FILE *fp)
     }
   XML_ParserFree(parser);
 
-  // adapt package count
-  pool->nsolvables += pd.pack;
-  repo->nsolvables += pd.pack;
-  repo->end += pd.pack;
-
   free(pd.content);
   free(pd.evrspace);
 }
index f9a06f1..2930313 100644 (file)
@@ -46,8 +46,6 @@ enum state {
   NUMSTATES
 };
 
-#define PACK_BLOCK 255
-
 
 struct stateswitch {
   enum state from;
@@ -99,10 +97,9 @@ struct parsedata {
   int lcontent;
   int acontent;
   int docontent;
-  int pack;
   Pool *pool;
   Repo *repo;
-  Solvable *start;
+  Solvable *solvable;
   char *kind;
 
   struct stateswitch *swtab[NUMSTATES];
@@ -243,8 +240,9 @@ startElement(void *userData, const char *name, const char **atts)
 {
   struct parsedata *pd = userData;
   Pool *pool = pd->pool;
-  Solvable *s = pd->start ? pd->start + pd->pack : 0;
+  Solvable *s = pd->solvable;
   struct stateswitch *sw;
+  Id id;
 
   if (pd->depth != pd->statedepth)
     {
@@ -290,24 +288,20 @@ startElement(void *userData, const char *name, const char **atts)
          if (pd->kind && !strcmp(pd->kind, "patch"))
            {
              s->repo = pd->repo;
+             pd->repo->nsolvables++;
              if (!s->arch)
                s->arch = ARCH_NOARCH;
              s->provides = repo_addid_dep(pd->repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
-             pd->pack++;
            }
          pd->kind = "atom";
          pd->state = STATE_PATCH;
        }
       else
         pd->kind = "patch";
-      if ((pd->pack & PACK_BLOCK) == 0)
-        {
-          pool->solvables = realloc(pool->solvables, (pool->nsolvables + pd->pack + PACK_BLOCK + 1) * sizeof(Solvable));
-          pd->start = pool->solvables + pool->nsolvables;
-          memset(pd->start + pd->pack, 0, (PACK_BLOCK + 1) * sizeof(Solvable));
-        }
+      id = repo_add_solvable(pd->repo);
+      pd->solvable = pool->solvables + id;
 #if 0
-      fprintf(stderr, "package #%d\n", pd->pack);
+      fprintf(stderr, "package #%d\n", id);
 #endif
       break;
     case STATE_VERSION:
@@ -377,7 +371,7 @@ endElement(void *userData, const char *name)
 {
   struct parsedata *pd = userData;
   Pool *pool = pd->pool;
-  Solvable *s = pd->start ? pd->start + pd->pack : 0;
+  Solvable *s = pd->solvable;
 
   if (pd->depth != pd->statedepth)
     {
@@ -397,12 +391,12 @@ endElement(void *userData, const char *name)
       if (!strcmp(name, "patch") && strcmp(pd->kind, "patch"))
        break;  /* already closed */
       s->repo = pd->repo;
+      pd->repo->nsolvables++;
       if (!s->arch)
        s->arch = ARCH_NOARCH;
       if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
         s->provides = repo_addid_dep(pd->repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
       s->supplements = repo_fix_legacy(pd->repo, s->provides, s->supplements);
-      pd->pack++;
       break;
     case STATE_NAME:
       s->name = str2id(pool, pd->content, 1);
@@ -452,12 +446,6 @@ repo_add_patchxml(Repo *repo, FILE *fp)
   int i, l;
   struct stateswitch *sw;
 
-  if (repo->start && repo->start + repo->nsolvables != pool->nsolvables)
-    abort();
-  if (!repo->start || repo->start == repo->end)
-    repo->start = pool->nsolvables;
-  repo->end = pool->nsolvables;
-
   memset(&pd, 0, sizeof(pd));
   for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
     {
@@ -487,9 +475,5 @@ repo_add_patchxml(Repo *repo, FILE *fp)
     }
   XML_ParserFree(parser);
 
-  pool->nsolvables += pd.pack;
-  repo->nsolvables += pd.pack;
-  repo->end += pd.pack;
-
   free(pd.content);
 }
index 0b929fd..d4eb8be 100644 (file)
@@ -529,11 +529,6 @@ repo_add_rpmdb(Repo *repo, Repo *ref)
   unsigned int refmask, h;
   int asolv;
 
-  if (repo->start && repo->start + repo->nsolvables != pool->nsolvables)
-    abort();
-  if (!repo->start || repo->start == repo->end)
-    repo->start = pool->nsolvables;
-  repo->end = pool->nsolvables;
   if (repo->start != repo->end)
     abort();           /* FIXME: rpmdbid */
 
@@ -564,24 +559,25 @@ repo_add_rpmdb(Repo *repo, Repo *ref)
          exit(1);
        }
       dbidp = (unsigned char *)&dbid;
-      pool->solvables = xrealloc(pool->solvables, (pool->nsolvables + 256) * sizeof(Solvable));
-      memset(pool->solvables + pool->nsolvables, 0, 256 * sizeof(Solvable));
       repo->rpmdbid = xcalloc(256, sizeof(unsigned int));
       asolv = 256;
       rpmheadsize = 0;
       rpmhead = 0;
       i = 0;
+      s = 0;
       while (dbc->c_get(dbc, &key, &data, DB_NEXT) == 0)
        {
+         if (!s)
+           {
+             id = repo_add_solvable(repo);
+             s = pool->solvables + id;
+           }
          if (i >= asolv)
            {
-             pool->solvables = xrealloc(pool->solvables, (pool->nsolvables + asolv + 256) * sizeof(Solvable));
-             memset(pool->solvables + pool->nsolvables + asolv, 0, 256 * sizeof(Solvable));
              repo->rpmdbid = xrealloc(repo->rpmdbid, (asolv + 256) * sizeof(unsigned int));
              memset(repo->rpmdbid + asolv, 0, 256 * sizeof(unsigned int));
              asolv += 256;
            }
-         pool->solvables[pool->nsolvables + i].repo = repo;
           if (key.size != 4)
            {
              fprintf(stderr, "corrupt Packages database (key size)\n");
@@ -617,10 +613,24 @@ repo_add_rpmdb(Repo *repo, Repo *ref)
          memcpy(rpmhead->data, (unsigned char *)data.data + 8, rpmhead->cnt * 16 + rpmhead->dcnt);
          rpmhead->dp = rpmhead->data + rpmhead->cnt * 16;
          repo->rpmdbid[i] = dbid;
-         if (rpm2solv(pool, repo, pool->solvables + pool->nsolvables + i, rpmhead))
-           i++;
+         if (rpm2solv(pool, repo, s, rpmhead))
+           {
+             s->repo = repo;
+             repo->nsolvables++;
+             i++;
+             s = 0;
+           }
+         else
+           {
+             memset(s, 0, sizeof(*s));         /* oops, reuse that one */
+           }
+       }
+      if (s)
+       {
+         /* oops, could not reuse. free it instead */
+          repo_free_solvable_block(repo, s - pool->solvables, 1, 1);
+         s = 0;
        }
-      nrpmids = i;
       dbc->c_close(dbc);
       db->close(db, 0);
       db = 0;
@@ -682,10 +692,6 @@ repo_add_rpmdb(Repo *repo, Repo *ref)
       rpmheadsize = 0;
       rpmhead = 0;
 
-      pool->solvables = xrealloc2(pool->solvables, (pool->nsolvables + nrpmids), sizeof(Solvable));
-      memset(pool->solvables + pool->nsolvables, 0, nrpmids * sizeof(Solvable));
-      repo->rpmdbid = calloc(nrpmids, sizeof(unsigned int));
-
       refhash = 0;
       refmask = 0;
       if (ref)
@@ -700,10 +706,15 @@ repo_add_rpmdb(Repo *repo, Repo *ref)
              refhash[h] = i + 1;       /* make it non-zero */
            }
        }
-      s = pool->solvables + pool->nsolvables;
+
+      repo->rpmdbid = xcalloc(nrpmids, sizeof(unsigned int));
+      id = repo_add_solvable_block(repo, nrpmids);
+      s = pool->solvables + id;
+
       for (i = 0; i < nrpmids; i++, rp++, s++)
        {
          s->repo = repo;
+         repo->nsolvables++;
          dbid = rp->dbid;
          repo->rpmdbid[i] = dbid;
          if (refhash)
@@ -817,10 +828,6 @@ repo_add_rpmdb(Repo *repo, Repo *ref)
     }
   if (rpmhead)
     free(rpmhead);
-  pool->nsolvables += nrpmids;
-  repo->nsolvables += nrpmids;
-  repo->end += nrpmids;
-
   if (db)
     db->close(db, 0);
 }
index 9cefc2d..1f90962 100644 (file)
@@ -96,10 +96,9 @@ struct parsedata {
   int acontent;
   int docontent;
   int numpacks;
-  int pack;
   Pool *pool;
   Repo *repo;
-  Solvable *start;
+  Solvable *solvable;
   struct stateswitch *swtab[NUMSTATES];
   enum state sbtab[NUMSTATES];
 };
@@ -238,8 +237,9 @@ startElement(void *userData, const char *name, const char **atts)
 {
   struct parsedata *pd = userData;
   Pool *pool = pd->pool;
-  Solvable *s = pd->start ? pd->start + pd->pack : 0;
+  Solvable *s = pd->solvable;
   struct stateswitch *sw;
+  Id id;
 
   if (pd->depth != pd->statedepth)
     {
@@ -270,23 +270,26 @@ startElement(void *userData, const char *name, const char **atts)
          if (!strcmp(*atts, "packages"))
            {
              pd->numpacks = atoi(atts[1]);
+             if (pd->numpacks < 0)
+               pd->numpacks = 0;
 #if 0
              fprintf(stderr, "numpacks: %d\n", pd->numpacks);
 #endif
-             pool->solvables = xrealloc2(pool->solvables, (pool->nsolvables + pd->numpacks), sizeof(Solvable));
-             pd->start = pool->solvables + pool->nsolvables;
-             memset(pd->start, 0, pd->numpacks * sizeof(Solvable));
+             id = repo_add_solvable_block(pd->repo, pd->numpacks);
+             pd->solvable = pool->solvables + id;
            }
        }
       break;
     case STATE_PACKAGE:
-      if (pd->pack >= pd->numpacks)
+      if (pd->numpacks > 0)
+       pd->numpacks--;
+      else
        {
-         fprintf(stderr, "repomd lied about the package number\n");
-         exit(1);
+         id = repo_add_solvable(pd->repo);
+         pd->solvable = pool->solvables + id;
        }
 #if 0
-      fprintf(stderr, "package #%d\n", pd->pack);
+      fprintf(stderr, "package #%d\n", pd->solvable - pool->solvables);
 #endif
       break;
     case STATE_VERSION:
@@ -356,7 +359,7 @@ endElement(void *userData, const char *name)
 {
   struct parsedata *pd = userData;
   Pool *pool = pd->pool;
-  Solvable *s = pd->start ? pd->start + pd->pack : 0;
+  Solvable *s = pd->solvable;
   Id id;
 
   if (pd->depth != pd->statedepth)
@@ -371,12 +374,13 @@ endElement(void *userData, const char *name)
     {
     case STATE_PACKAGE:
       s->repo = pd->repo;
+      pd->repo->nsolvables++;
       if (!s->arch)
         s->arch = ARCH_NOARCH;
       if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
         s->provides = repo_addid_dep(pd->repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
       s->supplements = repo_fix_legacy(pd->repo, s->provides, s->supplements);
-      pd->pack++;
+      pd->solvable++;
       break;
     case STATE_NAME:
       s->name = str2id(pool, pd->content, 1);
@@ -433,10 +437,6 @@ repo_add_rpmmd(Repo *repo, FILE *fp)
   int i, l;
   struct stateswitch *sw;
 
-  if (!repo->start || repo->start == repo->end)
-    repo->start = pool->nsolvables;
-  repo->end = pool->nsolvables;
-
   memset(&pd, 0, sizeof(pd));
   for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
     {
@@ -465,10 +465,7 @@ repo_add_rpmmd(Repo *repo, FILE *fp)
        break;
     }
   XML_ParserFree(parser);
-
-  pool->nsolvables += pd.pack;
-  repo->nsolvables += pd.pack;
-  repo->end += pd.pack;
-
+  if (pd.numpacks)
+    repo_free_solvable_block(repo, pd.solvable - pool->solvables, pd.numpacks, 1);
   free(pd.content);
 }
index 2fdcba8..11cab74 100644 (file)
@@ -16,8 +16,6 @@
 #include "attr_store.h"
 #include "repo_susetags.h"
 
-#define PACK_BLOCK 255
-
 static int
 split(char *l, char **sp, int m)
 {
@@ -150,12 +148,10 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
   int pack;
   char *sp[5];
   struct parsedata pd;
+  Id id;
 
-  if (!repo->start || repo->start == repo->end)
-    repo->start = pool->nsolvables;
-  repo->end = pool->nsolvables;
-
-  attr = new_store (pool);
+  if (with_attr)
+    attr = new_store(pool);
   memset(&pd, 0, sizeof(pd));
   line = malloc(1024);
   aline = 1024;
@@ -240,13 +236,10 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
          pd.kind = 0;
          if (line[3] == 't')
            pd.kind = "pattern";
-         if ((pack & PACK_BLOCK) == 0)
-           {
-             pool->solvables = realloc(pool->solvables, (pool->nsolvables + pack + PACK_BLOCK + 1) * sizeof(Solvable));
-             memset(pool->solvables + pool->nsolvables + pack, 0, (PACK_BLOCK + 1) * sizeof(Solvable));
-           }
-         s = pool->solvables + pool->nsolvables + pack;
+         id = repo_add_solvable(repo);
+         s = pool->solvables + id;
          s->repo = repo;
+         repo->nsolvables++;
          last_found_pack = pack;
          pack++;
           if (split(line + 5, sp, 5) != 4)
@@ -427,9 +420,6 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
   if (s)
     s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);
     
-  pool->nsolvables += pack;
-  repo->nsolvables += pack;
-  repo->end += pack;
   if (pd.tmp)
     free(pd.tmp);
   free(line);
index 542254f..2d7bd0d 100644 (file)
@@ -425,7 +425,7 @@ repo_write(Repo *repo, FILE *fp)
       if (s->freshens)
         write_idarray(fp, pool, needid, idarraydata + s->freshens);
       if (repo->rpmdbid)
-        write_u32(fp, repo->rpmdbid[i]);
+        write_u32(fp, repo->rpmdbid[i - repo->start]);
     }
 
   free(needid);