From: Michael Schroeder Date: Thu, 16 Jul 2009 14:02:50 +0000 (+0200) Subject: - add file list match X-Git-Tag: BASE-SuSE-Code-12_1-Branch~165^2~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=453c586e7d0d64c1162993fd7f70ec18d5e2f694;p=thirdparty%2Flibsolv.git - add file list match - make file list search faster --- diff --git a/examples/solv.c b/examples/solv.c index a64d9a07..24bd92b7 100644 --- a/examples/solv.c +++ b/examples/solv.c @@ -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); } diff --git a/src/repodata.c b/src/repodata.c index 49e14a93..e256245b 100644 --- a/src/repodata.c +++ b/src/repodata.c @@ -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))