- add file list match
authorMichael Schroeder <mls@suse.de>
Thu, 16 Jul 2009 14:02:50 +0000 (16:02 +0200)
committerMichael Schroeder <mls@suse.de>
Thu, 16 Jul 2009 14:02:50 +0000 (16:02 +0200)
- make file list search faster

examples/solv.c
src/repodata.c

index a64d9a0..24bd92b 100644 (file)
@@ -1250,8 +1250,10 @@ depglob(Pool *pool, char *name, Queue *job)
          return 1;
        }
     }
+
   if (strpbrk(name, "[*?") == 0)
     return 0;
+
   /* looks like a name glob. hard work. */
   for (p = 1; p < pool->nsolvables; p++)
     {
@@ -1392,6 +1394,30 @@ mkselect(Pool *pool, char *name, Queue *job)
   char *r, *r2;
   Id archid;
 
+  if (*name == '/')
+    {
+      Dataiterator di;
+      Queue q;
+      int match = 0;
+
+      queue_init(&q);
+      dataiterator_init(&di, pool, 0, 0, SOLVABLE_FILELIST, name, SEARCH_STRING|SEARCH_FILES|SEARCH_COMPLETE_FILELIST);
+      while (dataiterator_step(&di))
+       {
+         queue_push(&q, di.solvid);
+         dataiterator_skip_solvable(&di);
+       }
+      dataiterator_free(&di);
+      if (q.count)
+       {
+         printf("[using file list match for '%s']\n", name);
+         match = 1;
+         queue_push2(job, SOLVER_SOLVABLE_ONE_OF, pool_queuetowhatprovides(pool, &q));
+       }
+      queue_free(&q);
+      if (match)
+       return;
+    }
   if ((r = strpbrk(name, "<=>")) != 0)
     {
       /* relation case, support:
@@ -1486,8 +1512,8 @@ mkselect(Pool *pool, char *name, Queue *job)
          *r = '-';
        }
     }
-  fprintf(stderr, "nothing matches %s\n", name);
-  exit(0);
+  fprintf(stderr, "nothing matches '%s'\n", name);
+  exit(1);
 }
 
 
@@ -1629,11 +1655,11 @@ main(int argc, char **argv)
 {
   Pool *pool;
   Repo *commandlinerepo = 0;
+  Id *commandlinepkgs = 0;
   Id p, pp;
   struct repoinfo *repoinfos;
   int nrepoinfos = 0;
   int i, mode, newpkgs;
-  int needwhatprovidesrefresh;
   Queue job, checkq;
   Solver *solv = 0;
   Transaction *trans;
@@ -1682,42 +1708,46 @@ main(int argc, char **argv)
   setarch(pool);
   repoinfos = read_repoinfos(pool, REPOINFO_PATH, &nrepoinfos);
   read_repos(pool, repoinfos, nrepoinfos);
-  // FOR_REPOS(i, repo)
-  //   printf("%s: %d solvables\n", repo->name, repo->nsolvables);
-  needwhatprovidesrefresh = 1;
 
-  queue_init(&job);
-  for (i = 1; i < argc; i++)
+  if (mode == 0 || mode == SOLVER_INSTALL)
     {
-      if (mode == 0 || mode == SOLVER_INSTALL)
+      for (i = 1; i < argc; i++)
        {
          int l;
           l = strlen(argv[i]);
-         if (l > 4 && !strcmp(argv[i] + l - 4, ".rpm") && !access(argv[i], R_OK))
+         if (l <= 4 || strcmp(argv[i] + l - 4, ".rpm"))
+           continue;
+         if (access(argv[i], R_OK))
            {
-             FILE *fp;
-             if (!commandlinerepo)
-               commandlinerepo = repo_create(pool, "@commandline");
-             fp = fopen(argv[i], "r");
-             repo_add_rpms(commandlinerepo, (const char **)argv + i, 1, 0);
-             queue_push2(&job, SOLVER_SOLVABLE, commandlinerepo->end - 1);
-             continue;
+             perror(argv[i]);
+             exit(1);
            }
+         if (!commandlinepkgs)
+           commandlinepkgs = sat_calloc(argc, sizeof(Id));
+         if (!commandlinerepo)
+           commandlinerepo = repo_create(pool, "@commandline");
+         repo_add_rpms(commandlinerepo, (const char **)argv + i, 1, REPO_REUSE_REPODATA|REPO_NO_INTERNALIZE);
+         commandlinepkgs[i] = commandlinerepo->end - 1;
        }
-      if (needwhatprovidesrefresh)
+      if (commandlinerepo)
+       repo_internalize(commandlinerepo);
+    }
+
+  // FOR_REPOS(i, repo)
+  //   printf("%s: %d solvables\n", repo->name, repo->nsolvables);
+  pool_addfileprovides(pool);
+  pool_createwhatprovides(pool);
+
+  queue_init(&job);
+  for (i = 1; i < argc; i++)
+    {
+      if (commandlinepkgs && commandlinepkgs[i])
        {
-         pool_addfileprovides(pool);
-         pool_createwhatprovides(pool);
-         needwhatprovidesrefresh = 0;
+         queue_push2(&job, SOLVER_SOLVABLE, commandlinepkgs[i]);
+         continue;
        }
       mkselect(pool, argv[i], &job);
     }
-  if (needwhatprovidesrefresh)
-    {
-      pool_addfileprovides(pool);
-      pool_createwhatprovides(pool);
-      needwhatprovidesrefresh = 0;
-    }
   if (!job.count && mode == SOLVER_UPDATE)
     updateall = 1;
   else if (!job.count)
@@ -1743,6 +1773,7 @@ main(int argc, char **argv)
       queue_free(&job);
       pool_free(pool);
       free_repoinfos(repoinfos, nrepoinfos);
+      sat_free(commandlinepkgs);
       exit(0);
     }
 
@@ -2157,5 +2188,6 @@ rerunsolver:
   queue_free(&job);
   pool_free(pool);
   free_repoinfos(repoinfos, nrepoinfos);
+  sat_free(commandlinepkgs);
   exit(0);
 }
index 49e14a9..e256245 100644 (file)
@@ -1191,7 +1191,7 @@ dataiterator_filelistcheck(Dataiterator *di)
   for (j = 1; j < data->nkeys; j++)
     if (data->keys[j].name != REPOSITORY_SOLVABLES && data->keys[j].name != SOLVABLE_FILELIST)
       break;
-  return j == data->nkeys && needcomplete ? 1 : 0;
+  return j == data->nkeys && !needcomplete ? 0 : 1;
 }
 
 int
@@ -1423,6 +1423,13 @@ dataiterator_step(Dataiterator *di)
 
       if (di->matcher.match)
        {
+         /* simple pre-check so that we don't need to stringify */
+         if (di->keyname == SOLVABLE_FILELIST && di->key->type == REPOKEY_TYPE_DIRSTRARRAY && di->matcher.match && (di->matcher.flags & (SEARCH_FILES|SEARCH_NOCASE|SEARCH_STRINGMASK)) == (SEARCH_FILES|SEARCH_STRING))
+           {
+             int l = strlen(di->matcher.match) - strlen(di->kv.str);
+             if (l < 0 || strcmp(di->matcher.match + l, di->kv.str))
+               continue;
+           }
          if (!repodata_stringify(di->pool, di->data, di->key, &di->kv, di->flags))
            {
              if (di->keyname && (di->key->type == REPOKEY_TYPE_FIXARRAY || di->key->type == REPOKEY_TYPE_FLEXARRAY))