X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Frepo.c;h=4a72485c58dd5102bff098a8686d1bc702492c70;hb=5e90275664388c6cb7f3f7fc6f5ed5b2004814f6;hp=bd9cb219fa370cde689b4a055f9bde8b5cb79fb8;hpb=35bcf83488fc947ae04f10173133ce7ec71e04d1;p=platform%2Fupstream%2Flibsolv.git diff --git a/src/repo.c b/src/repo.c index bd9cb21..4a72485 100644 --- a/src/repo.c +++ b/src/repo.c @@ -46,6 +46,7 @@ repo_create(Pool *pool, const char *name) repo = (Repo *)sat_calloc(1, sizeof(*repo)); pool->repos = (Repo **)sat_realloc2(pool->repos, pool->nrepos + 1, sizeof(Repo *)); pool->repos[pool->nrepos++] = repo; + repo->repoid = pool->nrepos; repo->name = name ? strdup(name) : 0; repo->pool = pool; repo->start = pool->nsolvables; @@ -275,6 +276,8 @@ repo_free(Repo *repo, int reuseids) int i; pool_freewhatprovides(pool); + if (repo == pool->installed) + pool->installed = 0; if (reuseids && repo->end == pool->nsolvables) { @@ -296,7 +299,12 @@ repo_free(Repo *repo, int reuseids) if (i == pool->nrepos) /* repo not in pool, return */ return; if (i < pool->nrepos - 1) - memmove(pool->repos + i, pool->repos + i + 1, (pool->nrepos - 1 - i) * sizeof(Repo *)); + { + memmove(pool->repos + i, pool->repos + i + 1, (pool->nrepos - 1 - i) * sizeof(Repo *)); + /* fix repo ids */ + for (; i < pool->nrepos - 1; i++) + pool->repos[i]->repoid = i + 1; + } pool->nrepos--; repo_freedata(repo); } @@ -315,13 +323,43 @@ repo_freeallrepos(Pool *pool, int reuseids) pool_free_solvable_block(pool, 2, pool->nsolvables - 2, reuseids); } + +#define REPO_SIDEDATA_BLOCK 63 + +void * +repo_sidedata_create(Repo *repo, size_t size) +{ + return sat_calloc_block(repo->end - repo->start, size, REPO_SIDEDATA_BLOCK); +} + +void * +repo_sidedata_extend(Repo *repo, void *b, size_t size, Id p, int count) +{ + int n = repo->end - repo->start; + if (p < repo->start) + { + int d = repo->start - p; + b = sat_extend(b, n, d, size, REPO_SIDEDATA_BLOCK); + memmove((char*)b + d * size, b, n * size); + memset(b, 0, d * size); + n += d; + } + if (p + count > repo->end) + { + int d = p + count - repo->end; + b = sat_extend(b, n, d, size, REPO_SIDEDATA_BLOCK); + memset((char*)b + n * size, 0, d * size); + } + return b; +} + Offset -repo_fix_legacy(Repo *repo, Offset provides, Offset supplements) +repo_fix_supplements(Repo *repo, Offset provides, Offset supplements, Offset freshens) { Pool *pool = repo->pool; Id id, idp, idl; char buf[1024], *p, *dep; - int i; + int i, l; if (provides) { @@ -393,9 +431,9 @@ repo_fix_legacy(Repo *repo, Offset provides, Offset supplements) *p++ = 0; idp = str2id(pool, buf, 1); /* strip trailing slashes */ - i = strlen(p); - while (i > 1 && p[i - 1] == '/') - p[--i] = 0; + l = strlen(p); + while (l > 1 && p[l - 1] == '/') + p[--l] = 0; id = str2id(pool, p, 1); id = rel2id(pool, idp, id, REL_WITH, 1); id = rel2id(pool, NAMESPACE_SPLITPROVIDES, id, REL_NAMESPACE, 1); @@ -403,83 +441,144 @@ repo_fix_legacy(Repo *repo, Offset provides, Offset supplements) } } } - if (!supplements) - return 0; - for (i = supplements; repo->idarraydata[i]; i++) + if (supplements) { - id = repo->idarraydata[i]; - if (ISRELDEP(id)) - continue; - dep = (char *)id2str(pool, id); - if (!strncmp(dep, "system:modalias(", 16)) - dep += 7; - if (!strncmp(dep, "modalias(", 9) && dep[9] && dep[10] && strlen(dep) < sizeof(buf)) + for (i = supplements; repo->idarraydata[i]; i++) { - strcpy(buf, dep); - p = strchr(buf + 9, ':'); - 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, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1); - id = rel2id(pool, idp, id, REL_AND, 1); - } - else + id = repo->idarraydata[i]; + if (ISRELDEP(id)) + continue; + dep = (char *)id2str(pool, id); + if (!strncmp(dep, "system:modalias(", 16)) + dep += 7; + if (!strncmp(dep, "modalias(", 9) && dep[9] && dep[10] && strlen(dep) < sizeof(buf)) { - p = buf + 9; - p[strlen(p) - 1] = 0; - id = str2id(pool, p, 1); - id = rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1); + strcpy(buf, dep); + p = strchr(buf + 9, ':'); + 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, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1); + id = rel2id(pool, idp, id, REL_AND, 1); + } + else + { + p = buf + 9; + p[strlen(p) - 1] = 0; + id = str2id(pool, p, 1); + id = rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1); + } + if (id) + repo->idarraydata[i] = id; } - if (id) - repo->idarraydata[i] = id; - } - else if (!strncmp(dep, "packageand(", 11) && strlen(dep) < sizeof(buf)) - { - strcpy(buf, dep); - id = 0; - dep = buf + 11; - while ((p = strchr(dep, ':')) != 0) + else if (!strncmp(dep, "packageand(", 11) && strlen(dep) < sizeof(buf)) { - if (p == dep) + strcpy(buf, dep); + id = 0; + dep = buf + 11; + while ((p = strchr(dep, ':')) != 0) + { + if (p == dep) + { + dep = p + 1; + continue; + } + *p++ = 0; + idp = str2id(pool, dep, 1); + if (id) + id = rel2id(pool, id, idp, REL_AND, 1); + else + id = idp; + dep = p; + } + if (dep[0] && dep[1]) { - dep = p + 1; - continue; + dep[strlen(dep) - 1] = 0; + idp = str2id(pool, dep, 1); + if (id) + id = rel2id(pool, id, idp, REL_AND, 1); + else + id = idp; } - *p++ = 0; - idp = str2id(pool, dep, 1); if (id) - id = rel2id(pool, id, idp, REL_AND, 1); - else - id = idp; - dep = p; + repo->idarraydata[i] = id; } - if (dep[0] && dep[1]) + else if (!strncmp(dep, "filesystem(", 11) && strlen(dep) < sizeof(buf)) { - dep[strlen(dep) - 1] = 0; - idp = str2id(pool, dep, 1); - if (id) - id = rel2id(pool, id, idp, REL_AND, 1); - else - id = idp; + strcpy(buf, dep + 11); + if ((p = strrchr(buf, ')')) != 0) + *p = 0; + id = str2id(pool, buf, 1); + id = rel2id(pool, NAMESPACE_FILESYSTEM, id, REL_NAMESPACE, 1); + repo->idarraydata[i] = id; } - if (id) - repo->idarraydata[i] = id; } } + if (freshens && repo->idarraydata[freshens]) + { + Id idsupp = 0, idfresh = 0; + if (!supplements) + return freshens; + for (i = supplements; repo->idarraydata[i]; i++) + { + if (!idsupp) + idsupp = repo->idarraydata[i]; + else + idsupp = rel2id(pool, idsupp, repo->idarraydata[i], REL_OR, 1); + } + for (i = freshens; repo->idarraydata[i]; i++) + { + if (!idfresh) + idfresh = repo->idarraydata[i]; + else + idfresh = rel2id(pool, idfresh, repo->idarraydata[i], REL_OR, 1); + } + if (!idsupp) + idsupp = idfresh; + else + idsupp = rel2id(pool, idsupp, idfresh, REL_AND, 1); + supplements = repo_addid_dep(repo, 0, idsupp, 0); + } return supplements; } +Offset +repo_fix_conflicts(Repo *repo, Offset conflicts) +{ + char buf[1024], *p, *dep; + Pool *pool = repo->pool; + Id id; + int i; + + if (!conflicts) + return conflicts; + for (i = conflicts; repo->idarraydata[i]; i++) + { + id = repo->idarraydata[i]; + if (ISRELDEP(id)) + continue; + dep = (char *)id2str(pool, id); + if (!strncmp(dep, "otherproviders(", 15) && strlen(dep) < sizeof(buf) - 2) + { + strcpy(buf, dep + 15); + if ((p = strchr(buf, ')')) != 0) + *p = 0; + id = str2id(pool, buf, 1); + id = rel2id(pool, NAMESPACE_OTHERPROVIDERS, id, REL_NAMESPACE, 1); + repo->idarraydata[i] = id; + } + } + return conflicts; +} + struct matchdata { Pool *pool; - const char *match; int flags; -#if 0 - regex_t regex; -#endif + Datamatcher matcher; int stop; int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv); void *callback_data; @@ -489,62 +588,13 @@ int repo_matchvalue(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv) { struct matchdata *md = cbdata; - int flags = md->flags; - if ((flags & SEARCH_STRINGMASK) != 0) + if (md->matcher.match) { - switch (key->type) - { - case REPOKEY_TYPE_ID: - case REPOKEY_TYPE_IDARRAY: - if (data && data->localpool) - kv->str = stringpool_id2str(&data->spool, kv->id); - else - kv->str = id2str(s->repo->pool, kv->id); - break; - case REPOKEY_TYPE_STR: - break; - default: - return 0; - } - switch ((flags & SEARCH_STRINGMASK)) - { - case SEARCH_SUBSTRING: - if (flags & SEARCH_NOCASE) - { - if (!strcasestr(kv->str, md->match)) - return 0; - } - else - { - if (!strstr(kv->str, md->match)) - return 0; - } - break; - case SEARCH_STRING: - if (flags & SEARCH_NOCASE) - { - if (strcasecmp(md->match, kv->str)) - return 0; - } - else - { - if (strcmp(md->match, kv->str)) - return 0; - } - break; - case SEARCH_GLOB: - if (fnmatch(md->match, kv->str, (flags & SEARCH_NOCASE) ? FNM_CASEFOLD : 0)) - return 0; - break; -#if 0 - case SEARCH_REGEX: - if (regexec(&md->regexp, kv->str, 0, NULL, 0)) - return 0; -#endif - default: - return 0; - } + if (!repodata_stringify(md->pool, data, key, kv, md->flags)) + return 0; + if (!datamatcher_match(&md->matcher, kv->str)) + return 0; } md->stop = md->callback(md->callback_data, s, data, key, kv); return md->stop; @@ -564,7 +614,6 @@ static Repokey solvablekeys[RPM_RPMDBID - SOLVABLE_NAME + 1] = { { SOLVABLE_SUGGESTS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE }, { SOLVABLE_SUPPLEMENTS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE }, { SOLVABLE_ENHANCES, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE }, - { SOLVABLE_FRESHENS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE }, { RPM_RPMDBID, REPOKEY_TYPE_U32, 0, KEY_STORAGE_SOLVABLE }, }; @@ -572,11 +621,14 @@ static void domatch_idarray(Solvable *s, Id keyname, struct matchdata *md, Id *ida) { KeyValue kv; + kv.entry = 0; + kv.parent = 0; for (; *ida && !md->stop; ida++) { kv.id = *ida; kv.eof = ida[1] ? 0 : 1; repo_matchvalue(md, s, 0, solvablekeys + (keyname - SOLVABLE_NAME), &kv); + kv.entry++; } } @@ -586,9 +638,10 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md) KeyValue kv; Pool *pool = repo->pool; Repodata *data; - Solvable *s; int i, j, flags; + Solvable *s; + kv.parent = 0; md->stop = 0; if (!p) { @@ -601,10 +654,14 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md) } return; } - s = pool->solvables + p; + else if (p < 0) + /* The callback only supports solvables, so we can't iterate over the + extra things. */ + return; flags = md->flags; if (!(flags & SEARCH_NO_STORAGE_SOLVABLE)) { + s = pool->solvables + p; switch(keyname) { case 0: @@ -680,11 +737,6 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md) domatch_idarray(s, SOLVABLE_ENHANCES, md, repo->idarraydata + s->enhances); if (keyname || md->stop > SEARCH_NEXT_KEY) return; - case SOLVABLE_FRESHENS: - if (s->freshens) - domatch_idarray(s, SOLVABLE_FRESHENS, md, repo->idarraydata + s->freshens); - if (keyname || md->stop > SEARCH_NEXT_KEY) - return; case RPM_RPMDBID: if (repo->rpmdbid) { @@ -703,6 +755,8 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md) { if (p < data->start || p >= data->end) continue; + if (keyname && !repodata_precheck_keyname(data, keyname)) + continue; if (data->state == REPODATA_STUB) { if (keyname) @@ -721,7 +775,7 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md) } if (data->state == REPODATA_ERROR) continue; - repodata_search(data, p - data->start, keyname, repo_matchvalue, md); + repodata_search(data, p, keyname, md->flags, repo_matchvalue, md); if (md->stop > SEARCH_NEXT_KEY) break; } @@ -734,170 +788,230 @@ repo_search(Repo *repo, Id p, Id keyname, const char *match, int flags, int (*ca memset(&md, 0, sizeof(md)); md.pool = repo->pool; - md.match = match; md.flags = flags; md.callback = callback; md.callback_data = cbdata; + if (match) + datamatcher_init(&md.matcher, match, flags); repo_search_md(repo, p, keyname, &md); + if (match) + datamatcher_free(&md.matcher); } const char * -repo_lookup_str(Solvable *s, Id key) +repo_lookup_str(Repo *repo, Id entry, Id keyname) { - Repo *repo = s->repo; Pool *pool = repo->pool; Repodata *data; - int i, j, n; + int i, j; - switch(key) + switch(keyname) { case SOLVABLE_NAME: - return id2str(pool, s->name); + return id2str(pool, pool->solvables[entry].name); case SOLVABLE_ARCH: - return id2str(pool, s->arch); + return id2str(pool, pool->solvables[entry].arch); case SOLVABLE_EVR: - return id2str(pool, s->evr); + return id2str(pool, pool->solvables[entry].evr); case SOLVABLE_VENDOR: - return id2str(pool, s->vendor); + return id2str(pool, pool->solvables[entry].vendor); } - n = s - pool->solvables; for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) { - if (n < data->start || n >= data->end) + if (entry != SOLVID_META && (entry < data->start || entry >= data->end)) + continue; + if (!repodata_precheck_keyname(data, keyname)) continue; for (j = 1; j < data->nkeys; j++) { - if (data->keys[j].name == key && (data->keys[j].type == REPOKEY_TYPE_ID || data->keys[j].type == REPOKEY_TYPE_CONSTANTID || data->keys[j].type == REPOKEY_TYPE_STR)) - return repodata_lookup_str(data, n - data->start, j); + if (data->keys[j].name == keyname && (data->keys[j].type == REPOKEY_TYPE_ID || data->keys[j].type == REPOKEY_TYPE_CONSTANTID || data->keys[j].type == REPOKEY_TYPE_STR)) + return repodata_lookup_str(data, entry, keyname); } } return 0; } -int -repo_lookup_num(Solvable *s, Id key) + +unsigned int +repo_lookup_num(Repo *repo, Id entry, Id keyname, unsigned int notfound) { - Repo *repo = s->repo; - Pool *pool = repo->pool; Repodata *data; - int i, j, n; + int i, j; - if (key == RPM_RPMDBID) + if (keyname == RPM_RPMDBID) { - if (repo->rpmdbid) - return repo->rpmdbid[(s - pool->solvables) - repo->start]; - return 0; + if (repo->rpmdbid && entry >= repo->start && entry < repo->end) + return repo->rpmdbid[entry - repo->start]; + return notfound; } - n = s - pool->solvables; for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) { - if (n < data->start || n >= data->end) + if (entry != SOLVID_META && (entry < data->start || entry >= data->end)) + continue; + if (!repodata_precheck_keyname(data, keyname)) continue; for (j = 1; j < data->nkeys; j++) { - if (data->keys[j].name == key + if (data->keys[j].name == keyname && (data->keys[j].type == REPOKEY_TYPE_U32 || data->keys[j].type == REPOKEY_TYPE_NUM || data->keys[j].type == REPOKEY_TYPE_CONSTANT)) { unsigned value; - if (repodata_lookup_num(data, n - data->start, j, &value)) + if (repodata_lookup_num(data, entry, keyname, &value)) return value; } } } - return 0; + return notfound; } +Id +repo_lookup_id(Repo *repo, Id entry, Id keyname) +{ + Repodata *data; + int i, j; -/* - * generic attribute lookup - * returns non-zero if found - * zero if not found - * (XXX: return value is broken atm!) - */ + switch(keyname) + { + case SOLVABLE_NAME: + return repo->pool->solvables[entry].name; + case SOLVABLE_ARCH: + return repo->pool->solvables[entry].arch; + case SOLVABLE_EVR: + return repo->pool->solvables[entry].evr; + case SOLVABLE_VENDOR: + return repo->pool->solvables[entry].vendor; + } + for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) + { + if (entry != SOLVID_META && (entry < data->start || entry >= data->end)) + continue; + if (!repodata_precheck_keyname(data, keyname)) + continue; + for (j = 1; j < data->nkeys; j++) + { + if (data->keys[j].name == keyname && (data->keys[j].type == REPOKEY_TYPE_ID || data->keys[j].type == REPOKEY_TYPE_CONSTANTID)) + { + Id id = repodata_lookup_id(data, entry, keyname); + if (id) + { + if (data->localpool) + id = repodata_globalize_id(data, id); + return id; + } + } + } + } + return 0; +} -int -repo_lookup(Solvable *s, Id key, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata) +const unsigned char * +repo_lookup_bin_checksum(Repo *repo, Id entry, Id keyname, Id *typep) { - Repo *repo = s->repo; - Pool *pool = repo->pool; Repodata *data; - int i, s_id; - - s_id = s - pool->solvables; + int i, j; for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) { - if (s_id < data->start || s_id >= data->end) + if (entry != SOLVID_META && (entry < data->start || entry >= data->end)) continue; - repodata_search(data, s_id - data->start, key, callback, cbdata); - return 1; + if (!repodata_precheck_keyname(data, keyname)) + continue; + for (j = 1; j < data->nkeys; j++) + { + if (data->keys[j].name == keyname) + { + const unsigned char *chk = repodata_lookup_bin_checksum(data, entry, keyname, typep); + if (chk) + return chk; + } + } } + *typep = 0; return 0; } +int +repo_lookup_void(Repo *repo, Id entry, Id keyname) +{ + Repodata *data; + int i, j; + for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) + { + if (entry != SOLVID_META && (entry < data->start || entry >= data->end)) + continue; + if (!repodata_precheck_keyname(data, keyname)) + continue; + for (j = 1; j < data->nkeys; j++) + { + if (data->keys[j].name == keyname + && (data->keys[j].type == REPOKEY_TYPE_VOID)) + { + if (repodata_lookup_void(data, entry, keyname)) + return 1; + } + } + } + return 0; +} /***********************************************************************/ Repodata * -repo_add_repodata(Repo *repo) +repo_add_repodata(Repo *repo, int localpool) { Repodata *data; repo->nrepodata++; repo->repodata = sat_realloc2(repo->repodata, repo->nrepodata, sizeof(*data)); data = repo->repodata + repo->nrepodata - 1; - repodata_init(data, repo, 0); + repodata_init(data, repo, localpool); return data; } -static Repodata * -findrepodata(Repo *repo, Id p, Id keyname) +Repodata * +repo_last_repodata(Repo *repo) { int i; - Repodata *data; - - /* FIXME: enter nice code here */ - for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) - if (p >= data->start && p < data->end) - return data; - for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) - if (p == data->end) - break; - if (i < repo->nrepodata) - { - repodata_extend(data, p); - return data; - } - return repo_add_repodata(repo); + for (i = repo->nrepodata - 1; i >= 0; i--) + if (repo->repodata[i].state != REPODATA_STUB) + return repo->repodata + i; + return repo_add_repodata(repo, 0); } void repo_set_id(Repo *repo, Id p, Id keyname, Id id) { - Repodata *data = findrepodata(repo, p, keyname); - repodata_set_id(data, p - data->start, keyname, id); + Repodata *data = repo_last_repodata(repo); + repodata_set_id(data, p, keyname, id); } void repo_set_num(Repo *repo, Id p, Id keyname, Id num) { - Repodata *data = findrepodata(repo, p, keyname); - repodata_set_num(data, p - data->start, keyname, num); + Repodata *data = repo_last_repodata(repo); + repodata_set_num(data, p, keyname, num); } void repo_set_str(Repo *repo, Id p, Id keyname, const char *str) { - Repodata *data = findrepodata(repo, p, keyname); - repodata_set_str(data, p - data->start, keyname, str); + Repodata *data = repo_last_repodata(repo); + repodata_set_str(data, p, keyname, str); } void repo_set_poolstr(Repo *repo, Id p, Id keyname, const char *str) { - Repodata *data = findrepodata(repo, p, keyname); - repodata_set_poolstr(data, p - data->start, keyname, str); + Repodata *data = repo_last_repodata(repo); + repodata_set_poolstr(data, p, keyname, str); +} + +void +repo_add_poolstr_array(Repo *repo, Id p, Id keyname, const char *str) +{ + Repodata *data = repo_last_repodata(repo); + repodata_add_poolstr_array(data, p, keyname, str); } void @@ -907,10 +1021,19 @@ repo_internalize(Repo *repo) Repodata *data; for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) - if (data->attrs) + if (data->attrs || data->xattrs) repodata_internalize(data); } +void +repo_disable_paging(Repo *repo) +{ + int i; + Repodata *data; + + for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) + repodata_disable_paging(data); +} // EOF /* vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4: