- fix support for splitprovides
authorMichael Schroeder <mls@suse.de>
Fri, 11 Jan 2008 20:42:25 +0000 (20:42 +0000)
committerMichael Schroeder <mls@suse.de>
Fri, 11 Jan 2008 20:42:25 +0000 (20:42 +0000)
- add some unfinished code for DU queries

src/pool.c
src/pool.h
src/repo.c
src/solver.c
src/solver.h

index 75a0a51..c2eab07 100644 (file)
@@ -54,6 +54,7 @@ static const char *initpool_data[] = {
   "solvable:filemarker",
   "namespace:installed",
   "namespace:modalias",
+  "namespace:splitprovides",
   "system:system",
   "src",
   "nosrc",
@@ -632,12 +633,13 @@ pool_setdebuglevel(Pool *pool, int level)
 struct searchfiles {
   const char **files;
   int nfiles;
+  Map seen;
 };
 
 #define SEARCHFILES_BLOCK 127
 
 static void
-pool_addfileprovides_dep(Pool *pool, Id *ida, Map *seen, struct searchfiles *sf)
+pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct searchfiles *isf)
 {
   Id dep, sid;
   const char *s;
@@ -648,21 +650,27 @@ pool_addfileprovides_dep(Pool *pool, Id *ida, Map *seen, struct searchfiles *sf)
        {
          Reldep *rd;
          sid = pool->ss.nstrings + GETRELID(dep);
-         if (MAPTST(seen, sid))
+         if (MAPTST(&sf->seen, sid))
            {
              dep = 0;
              break;
            }
-         MAPSET(seen, sid);
+         MAPSET(&sf->seen, sid);
          rd = GETRELDEP(pool, dep);
          if (rd->flags < 8)
            dep = rd->name;
          else if (rd->flags == REL_NAMESPACE)
            {
-             if (rd->name == NAMESPACE_INSTALLED)
+             if (isf && (rd->name == NAMESPACE_INSTALLED || rd->name == NAMESPACE_SPLITPROVIDES))
                {
-                 dep = 0;      /* for now */
-                 break;
+                 sf = isf;
+                 isf = 0;
+                 if (MAPTST(&sf->seen, sid))
+                   {
+                     dep = 0;
+                     break;
+                   }
+                 MAPSET(&sf->seen, sid);
                }
              dep = rd->evr;
            }
@@ -671,15 +679,15 @@ pool_addfileprovides_dep(Pool *pool, Id *ida, Map *seen, struct searchfiles *sf)
              Id ids[2];
              ids[0] = rd->name;
              ids[1] = 0;
-             pool_addfileprovides_dep(pool, ids, seen, sf);
+             pool_addfileprovides_dep(pool, ids, sf, isf);
              dep = rd->evr;
            }
        }
       if (!dep)
        continue;
-      if (MAPTST(seen, dep))
+      if (MAPTST(&sf->seen, dep))
        continue;
-      MAPSET(seen, dep);
+      MAPSET(&sf->seen, dep);
       s = id2str(pool, dep);
       if (*s != '/')
        continue;
@@ -704,16 +712,17 @@ addfileprovides_cb(void *data, Solvable *s, Id key, const char *str)
 #endif
 
 void
-pool_addfileprovides(Pool *pool)
+pool_addfileprovides(Pool *pool, Repo *installed)
 {
   Solvable *s;
   Repo *repo;
-  Map seen;
-  struct searchfiles sf;
+  struct searchfiles sf, isf;
   int i;
 
-  map_init(&seen, pool->ss.nstrings + pool->nrels);
   memset(&sf, 0, sizeof(sf));
+  map_init(&sf.seen, pool->ss.nstrings + pool->nrels);
+  memset(&isf, 0, sizeof(isf));
+  map_init(&isf.seen, pool->ss.nstrings + pool->nrels);
 
   for (i = 1, s = pool->solvables + i; i < pool->nsolvables; i++, s++)
     {
@@ -721,38 +730,271 @@ pool_addfileprovides(Pool *pool)
       if (!repo)
        continue;
       if (s->obsoletes)
-        pool_addfileprovides_dep(pool, repo->idarraydata + s->obsoletes, &seen, &sf);
+        pool_addfileprovides_dep(pool, repo->idarraydata + s->obsoletes, &sf, &isf);
       if (s->conflicts)
-        pool_addfileprovides_dep(pool, repo->idarraydata + s->conflicts, &seen, &sf);
+        pool_addfileprovides_dep(pool, repo->idarraydata + s->conflicts, &sf, &isf);
       if (s->requires)
-        pool_addfileprovides_dep(pool, repo->idarraydata + s->requires, &seen, &sf);
+        pool_addfileprovides_dep(pool, repo->idarraydata + s->requires, &sf, &isf);
       if (s->recommends)
-        pool_addfileprovides_dep(pool, repo->idarraydata + s->recommends, &seen, &sf);
+        pool_addfileprovides_dep(pool, repo->idarraydata + s->recommends, &sf, &isf);
       if (s->suggests)
-        pool_addfileprovides_dep(pool, repo->idarraydata + s->suggests, &seen, &sf);
+        pool_addfileprovides_dep(pool, repo->idarraydata + s->suggests, &sf, &isf);
       if (s->supplements)
-        pool_addfileprovides_dep(pool, repo->idarraydata + s->supplements, &seen, &sf);
+        pool_addfileprovides_dep(pool, repo->idarraydata + s->supplements, &sf, &isf);
       if (s->enhances)
-        pool_addfileprovides_dep(pool, repo->idarraydata + s->enhances, &seen, &sf);
+        pool_addfileprovides_dep(pool, repo->idarraydata + s->enhances, &sf, &isf);
       if (s->freshens)
-        pool_addfileprovides_dep(pool, repo->idarraydata + s->freshens, &seen, &sf);
+        pool_addfileprovides_dep(pool, repo->idarraydata + s->freshens, &sf, &isf);
     }
-  map_free(&seen);
+  map_free(&sf.seen);
+  map_free(&isf.seen);
   POOL_DEBUG(SAT_DEBUG_STATS, "found %d file dependencies\n", sf.nfiles);
-  if (!sf.nfiles)
-    return;
+  POOL_DEBUG(SAT_DEBUG_STATS, "found %d installed file dependencies\n", isf.nfiles);
+  if (sf.nfiles)
+    {
+#if 0
+      for (i = 0; i < sf.nfiles; i++)
+       POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in filelist\n", sf.files[i]);
+#endif
+      if ((sf.nfiles & SEARCHFILES_BLOCK) == 0)
+       sf.files = sat_realloc2(sf.files, sf.nfiles + (SEARCHFILES_BLOCK + 1), sizeof(const char *));
+      sf.files[sf.nfiles++] = 0;
+#if 0
+      pool_search(0, SOLVABLE_FILELIST, (const char *)sf.files, SEARCH_STRING|SEARCH_MULTIPLE, addfileprovides_cb, 0);
+#endif
+      sat_free(sf.files);
+    }
+  if (isf.nfiles && installed)
+    {
 #if 0
-  for (i = 0; i < sf.nfiles; i++)
-    POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in filelist\n", sf.files[i]);
+      for (i = 0; i < isf.nfiles; i++)
+       POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in installed filelist\n", isf.files[i]);
 #endif
-  if ((sf.nfiles & SEARCHFILES_BLOCK) == 0)
-    sf.files = sat_realloc2(sf.files, sf.nfiles + (SEARCHFILES_BLOCK + 1), sizeof(const char *));
-  sf.files[sf.nfiles++] = 0;
+      if ((isf.nfiles & SEARCHFILES_BLOCK) == 0)
+       isf.files = sat_realloc2(isf.files, isf.nfiles + (SEARCHFILES_BLOCK + 1), sizeof(const char *));
+      isf.files[isf.nfiles++] = 0;
 #if 0
-  pool_search(0, SOLVABLE_FILELIST, (const char *)sf.files, SEARCH_STRING|SEARCH_MULTIPLE, addfileprovides_cb, 0);
+      repo_search(installed, 0, SOLVABLE_FILELIST, (const char *)isf.files, SEARCH_STRING|SEARCH_MULTIPLE, addfileprovides_cb, 0);
 #endif
-  sat_free(sf.files);
+      sat_free(isf.files);
+    }
   pool_freewhatprovides(pool); /* as we have added provides */
 }
 
+#if 0
+
+struct mountpoint {
+  const char *path;
+  int kbytes;
+  int files;
+};
+
+struct mptree {
+  Id sibling;
+  Id child;
+  const char *comp;
+  int compl;
+  Id mountpoint;
+};
+
+struct cbdata {
+  struct mountpoint *mps;
+  Id *dirmap;
+  int nmap;
+};
+
+static int
+pool_fill_DU_add_cb(void *data, Solvable *s, Id key, const char *str)
+{
+  struct cbdata *cbdata = data;
+  Id mp, dirnum, kbytes, files;
+
+  dp = data_read_id(dp, &dirnum);
+  dp = data_read_id(dp, &kbytes);
+  data_read_id(dp, &files);
+  if (dirnum < 0 || dirnum > cbdata->nmap)
+    return 0;
+  mp = cbdata->dirmap[dirnum];
+  if (mp >= 0)
+    {
+      cbdata->mps[mp].kbytes += kbytes;
+      cbdata->mps[mp].files += files;
+    }
+  return 0;
+}
+
+static int
+pool_fill_DU_sub_cb(void *data, Solvable *s, Id key, const char *str)
+{
+  struct cbdata *cbdata = data;
+  Id mp, dirnum, kbytes, files;
+
+  dp = data_read_id(dp, &dirnum);
+  dp = data_read_id(dp, &kbytes);
+  data_read_id(dp, &files);
+  if (dirnum < 0 || dirnum > cbdata->nmap)
+    return 0;
+  mp = cbdata->dirmap[dirnum];
+  if (mp >= 0)
+    {
+      cbdata->mps[mp].kbytes -= kbytes;
+      cbdata->mps[mp].files -= files;
+    }
+  return 0;
+}
+
+static void
+propagate_mountpoints(struct mptree *mptree, int pos, Id mountpoint)
+{
+  int i;
+  if (mptree[pos].mountpoint == -1)
+    mptree[pos].mountpoint = mountpoint;
+  else
+    mountpoint = mptree[pos].mountpoint;
+  for (i = mptree[pos].child; i; i = mptree[i].sibling)
+    propagate_mountpoints(mptree, i, mountpoint);
+}
+
+void
+pool_fill_DU(Pool *pool, struct mountpoint *mps, int nmps)
+{
+  char *path, *p;
+  Id *dirmap;
+  struct mptree *mptree;
+  int nmptree;
+  int pos;
+  int mp;
+
+  struct matchdata md;
+  struct cbdata cbdata;
+
+  memset(&md, 0, sizeof(md));
+  md.pool = 0;
+  md.matchstr = 0;
+  md.flags = 0;
+  md.callback = 0;
+  md.callback_data = &cbdata
+
+  cbdata.mps = mps;
+  cbdata.dirmap = 0;
+  cbdata.nmap = 0;
+
+  mptree = sat_malloc2(16, sizeof(mptree));
+
+  /* our root node */
+  mptree[0].sibling = 0;
+  mptree[0].child = 0;
+  mptree[0].comp = 0;
+  mptree[0].compl = 0;
+  mptree[0].mountpoint = -1;
+  nmptree = 1;
+  
+  /* create component tree */
+  for (mp = 0; mp < nmps; mp++)
+    {
+      pos = 0;
+      path = mps[mp].path;
+      while(*path == '/')
+       path++;
+      while (*path)
+       {
+         if ((p = strchr('/', path)) == 0)
+           {
+             comp = path;
+             compl = strlen(comp);
+             path += compl;
+           }
+         else
+           {
+             comp = path;
+             compl = p - path;
+             path = p + 1;
+             while(*path == '/')
+               path++;
+           }
+          for (i = mptree[pos].child; i; i = mptree[i].sibling)
+           if (mptree[i].compl == compl && !strncmp(mptree[i].comp, comp, compl))
+             break;
+         if (!i)
+           {
+             /* create new node */
+             if ((nmptree & 15) == 0)
+               mptree = sat_realloc2(mptree, nmptree + 16, sizeof(mptree));
+             i = nmptree++;
+             mptree[i].sibling = mptree[pos].child;
+             mptree[i].child = 0;
+             mptree[i].comp = comp;
+             mptree[i].compl = compl;
+             mptree[i].mountpoint = -1;
+             mptree[pos].child = i;
+           }
+         pos = i;
+       }
+      mptree[pos].mountpoint = mp;
+    }
+  propagate_mountpoints(mptree, 0, mptree[0].mountpoint);
+
+  for_all_repos
+    {
+      for_all_repodatas_containing_DU
+       {
+         dirmap = xcalloc2(data->ndirs, sizeof(Id));
+         dirnum = 0;
+         for (;;)
+           {
+             parent = readid();
+             mp = parent ? dirmap[parent] : 0;
+             while (id = readid())
+               {
+                 if (mp < 0)
+                   {
+                     /* unconnected */
+                     dirmap[dirnum++] = mp;
+                     continue;
+                   }
+                 if (!mptree[mp].child)
+                   {
+                     dirmap[dirnum++] = -mp;
+                     continue;
+                   }
+                 comp = id2str(pool, id);
+                 compl = strlen(comp);
+                 for (i = mptree[mp].child; i; i = mptree[i].sibling)
+                   if (mptree[i].compl == compl && !strncmp(mptree[i].comp, comp, compl))
+                     break;
+                 dirmap[dirnum++] = i ? i : -mp;
+               }
+           }
+         for (i = 0; i < dirnum; i++)
+           {
+             mp = dirmap[i];
+             dirmap[i] = mptree[mp > 0 ? mp : -mp].mountpoint;
+           }
+         cbdata.nmap = dirnum;
+         cbdata.dirmap = dirmap;
+
+         md.callback = pool_fill_DU_add_cb;
+         for_solvables_to_be_installed()
+           {
+             if (p < data->start || p >= data->end)
+               continue;
+             repodata_search(data, p - data->start, SOLVABLE_DUDATA, &md);
+           }
+         md.callback = pool_fill_DU_sub_cb;
+         for_solvables_to_be_erased()
+           {
+             if (p < data->start || p >= data->end)
+               continue;
+             repodata_search(data, p - data->start, SOLVABLE_DUDATA, &md);
+           }
+
+         cbdata.dirmap = 0;
+         cbdata.nmap = 0;
+         sat_free(dirmap);
+       }
+    }
+}
+
+#endif
+
 // EOF
index 01beb33..1e0b58a 100644 (file)
@@ -46,15 +46,16 @@ extern "C" {
 #define SOLVABLE_FILEMARKER    17              // normal provides before this, generated file provides after this
 #define NAMESPACE_INSTALLED    18
 #define NAMESPACE_MODALIAS     19
-#define SYSTEM_SYSTEM          20
-#define ARCH_SRC               21
-#define ARCH_NOSRC             22
-#define ARCH_NOARCH            23
-#define REPODATA_EXTERNAL      24
-#define REPODATA_KEYS          25
-#define REPODATA_LOCATION      26
+#define NAMESPACE_SPLITPROVIDES 20
+#define SYSTEM_SYSTEM          21
+#define ARCH_SRC               22
+#define ARCH_NOSRC             23
+#define ARCH_NOARCH            24
+#define REPODATA_EXTERNAL      25
+#define REPODATA_KEYS          26
+#define REPODATA_LOCATION      27
 
-#define ID_NUM_INTERNAL                27
+#define ID_NUM_INTERNAL                28
 
 
 /* well known solvable */
@@ -207,7 +208,7 @@ extern const char *solvable2str(Pool *pool, Solvable *s);
  * Prepares a pool for solving
  */
 extern void pool_createwhatprovides(Pool *pool);
-extern void pool_addfileprovides(Pool *pool);
+extern void pool_addfileprovides(Pool *pool, struct _Repo *installed);
 extern void pool_freewhatprovides(Pool *pool);
 extern Id pool_queuetowhatprovides(Pool *pool, Queue *q);
 
index 094947a..a18ae6c 100644 (file)
@@ -318,7 +318,7 @@ Offset
 repo_fix_legacy(Repo *repo, Offset provides, Offset supplements)
 {
   Pool *pool = repo->pool;
-  Id id, idp, idl, idns;
+  Id id, idp, idl;
   char buf[1024], *p, *dep;
   int i;
 
@@ -381,10 +381,9 @@ repo_fix_legacy(Repo *repo, Offset provides, Offset supplements)
              p = buf + (p - dep);
              *p++ = 0;
              idp = str2id(pool, buf, 1);
-             idns = str2id(pool, "namespace:installed", 1);
              id = str2id(pool, p, 1);
-             id = rel2id(pool, idns, id, REL_NAMESPACE, 1);
-             id = rel2id(pool, idp, id, REL_AND, 1);
+             id = rel2id(pool, idp, id, REL_WITH, 1);
+             id = rel2id(pool, NAMESPACE_SPLITPROVIDES, id, REL_NAMESPACE, 1);
              supplements = repo_addid_dep(repo, supplements, id, 0);
            }
        }
@@ -403,14 +402,13 @@ repo_fix_legacy(Repo *repo, Offset provides, Offset supplements)
        {
          strcpy(buf, dep);
          p = strchr(buf + 9, ':');
-         idns = str2id(pool, "namespace:modalias", 1);
          if (p && p != buf + 9 && strchr(p + 1, ':'))
            {
              *p++ = 0;
              idp = str2id(pool, buf + 9, 1);
              p[strlen(p) - 1] = 0;
              id = str2id(pool, p, 1);
-             id = rel2id(pool, idns, id, REL_NAMESPACE, 1);
+             id = rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
              id = rel2id(pool, idp, id, REL_AND, 1);
            }
          else
@@ -418,7 +416,7 @@ repo_fix_legacy(Repo *repo, Offset provides, Offset supplements)
              p = buf + 9;
              p[strlen(p) - 1] = 0;
              id = str2id(pool, p, 1);
-             id = rel2id(pool, idns, id, REL_NAMESPACE, 1);
+             id = rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
            }
          if (id)
            repo->idarraydata[i] = id;
@@ -738,6 +736,30 @@ repo_search_md(Repo *repo, Id p, Id key, struct matchdata *md)
   md->stop = 0;
   if (!p)
     {
+#if 0
+      switch(key)
+       {
+        case 0:
+        case SOLVABLE_NAME:
+        case SOLVABLE_ARCH:
+        case SOLVABLE_EVR:
+        case SOLVABLE_VENDOR:
+        case SOLVABLE_PROVIDES:
+        case SOLVABLE_OBSOLETES:
+        case SOLVABLE_CONFLICTS:
+        case SOLVABLE_REQUIRES:
+        case SOLVABLE_RECOMMENDS:
+        case SOLVABLE_SUPPLEMENTS:
+        case SOLVABLE_SUGGESTS:
+        case SOLVABLE_ENHANCES:
+        case SOLVABLE_FRESHENS:
+         break;
+       default:
+         for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
+           repodata_search(data, -1, key, md);
+         return;
+       }
+#endif
       for (p = repo->start, s = repo->pool->solvables + p; p < repo->end; p++, s++)
        {
          if (s->repo == repo)
index 7b31c03..69057c3 100644 (file)
 
 
 int
+solver_splitprovides(Solver *solv, Id dep)
+{
+  Pool *pool = solv->pool;
+  Id p, *pp;
+  Reldep *rd;
+  Solvable *s;
+
+  if (!solv->dosplitprovides || !solv->installed)
+    return 0;
+  if (!ISRELDEP(dep))
+    return 0;
+  rd = GETRELDEP(pool, dep);
+  if (rd->flags != REL_WITH)
+    return 0;
+  FOR_PROVIDES(p, pp, dep)
+    {
+      s = pool->solvables + p;
+      if (s->repo == solv->installed && s->name == rd->name)
+       return 1;
+    }
+  return 0;
+}
+
+int
 solver_dep_installed(Solver *solv, Id dep)
 {
-  /* disable for now, splitprovides don't work anyway and it breaks
-     a testcase */
 #if 0
   Pool *pool = solv->pool;
   Id p, *pp;
@@ -75,6 +97,8 @@ dep_possible(Solver *solv, Id dep, Map *m)
            return 0;
          return dep_possible(solv, rd->evr, m);
        }
+      if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
+       return solver_splitprovides(solv, rd->evr);
       if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_INSTALLED)
        return solver_dep_installed(solv, rd->evr);
     }
index 98c476b..0ac879f 100644 (file)
@@ -58,6 +58,7 @@ typedef struct solver {
   int updatesystem;                    /* distupgrade */
   int allowvirtualconflicts;           /* false: conflicts on package name, true: conflicts on package provides */
   int noupdateprovide;                 /* true: update packages needs not to provide old package */
+  int dosplitprovides;                 /* true: consider legacy split provides */
   
   Rule *rules;                         /* all rules */
   Id nrules;                           /* index of the last rule */
@@ -140,6 +141,7 @@ extern Solver *solver_create(Pool *pool, Repo *installed);
 extern void solver_free(Solver *solv);
 extern void solver_solve(Solver *solv, Queue *job);
 extern int solver_dep_installed(Solver *solv, Id dep);
+extern int solver_splitprovides(Solver *solv, Id dep);
 
 extern Id solver_next_problem(Solver *solv, Id problem);
 extern Id solver_next_solution(Solver *solv, Id problem, Id solution);
@@ -169,6 +171,8 @@ solver_dep_fulfilled(Solver *solv, Id dep)
             return 0;
           return solver_dep_fulfilled(solv, rd->evr);
         }
+      if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
+        return solver_splitprovides(solv, rd->evr);
       if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_INSTALLED)
         return solver_dep_installed(solv, rd->evr);
     }