From: Michael Schroeder Date: Mon, 21 Feb 2011 14:34:47 +0000 (+0100) Subject: - add SUSETAGS_RECORD_SHARES feature to correctly handle shared data when extending... X-Git-Tag: BASE-SuSE-Code-12_1-Branch~137 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc53162b76d0243a586f31591fc9de6761229686;p=thirdparty%2Flibsolv.git - add SUSETAGS_RECORD_SHARES feature to correctly handle shared data when extending the repo --- diff --git a/ext/repo_susetags.c b/ext/repo_susetags.c index b5fff0cb..c75ad3ee 100644 --- a/ext/repo_susetags.c +++ b/ext/repo_susetags.c @@ -18,6 +18,11 @@ #include "tools_util.h" #include "repo_susetags.h" +struct datashare { + Id name; + Id evr; + Id arch; +}; struct parsedata { char *kind; Repo *repo; @@ -25,7 +30,7 @@ struct parsedata { int flags; struct parsedata_common common; int last_found_source; - char **share_with; + struct datashare *share_with; int nshare; Id (*dirs)[3]; // dirid, size, nfiles int ndirs; @@ -436,6 +441,33 @@ joinhash_lookup(Repo *repo, Hashtable ht, Hashmask hm, Id name, Id evr, Id arch) return 0; } +static Id +lookup_shared_id(Repodata *data, Id p, Id keyname, Id voidid, int uninternalized) +{ + Id r; + if (repodata_lookup_void(data, p, keyname)) + return voidid; + r = repodata_lookup_id(data, p, keyname); + if (r) + return r; + if (uninternalized && data->attrs) + { + Id *ap = data->attrs[p - data->start]; + if (ap) + { + for (; *ap; ap += 2) + { + if (data->keys[*ap].name != keyname) + continue; + if (data->keys[*ap].type == REPOKEY_TYPE_VOID) + return voidid; + if (data->keys[*ap].type == REPOKEY_TYPE_ID) + return ap[1]; + } + } + } + return 0; +} /* * parse susetags @@ -487,6 +519,41 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int s = 0; freshens = 0; + /* if this is a join setup the recorded share data */ + if (joinhash) + { + Repodata *sdata; + int i; + for (i = 0, sdata = repo->repodata; i < repo->nrepodata; i++, sdata++) + { + int p; + if (!repodata_has_keyname(sdata, SUSETAGS_SHARE_NAME)) + continue; + for (p = sdata->start; p < sdata->end; p++) + { + Id name, evr, arch; + name = lookup_shared_id(sdata, p, SUSETAGS_SHARE_NAME, pool->solvables[p].name, sdata == data); + if (!name) + continue; + evr = lookup_shared_id(sdata, p, SUSETAGS_SHARE_EVR, pool->solvables[p].evr, sdata == data); + if (!evr) + continue; + arch = lookup_shared_id(sdata, p, SUSETAGS_SHARE_ARCH, pool->solvables[p].arch, sdata == data); + if (!arch) + continue; + if (p - repo->start >= pd.nshare) + { + pd.share_with = sat_realloc2(pd.share_with, p - repo->start + 256, sizeof(*pd.share_with)); + memset(pd.share_with + pd.nshare, 0, (p - repo->start + 256 - pd.nshare) * sizeof(*pd.share_with)); + pd.nshare = p - repo->start + 256; + } + pd.share_with[p - repo->start].name = name; + pd.share_with[p - repo->start].evr = evr; + pd.share_with[p - repo->start].arch = arch; + } + } + } + /* * read complete file * @@ -832,14 +899,42 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int } continue; case CTAG('=', 'S', 'h', 'r'): - if (last_found_pack >= pd.nshare) - { - pd.share_with = sat_realloc2(pd.share_with, last_found_pack + 256, sizeof(*pd.share_with)); - memset(pd.share_with + pd.nshare, 0, (last_found_pack + 256 - pd.nshare) * sizeof(*pd.share_with)); - pd.nshare = last_found_pack + 256; - } - pd.share_with[last_found_pack] = strdup(line + 6); - continue; + { + Id name, evr, arch; + if (split(line + 6, sp, 5) != 4) + { + pool_debug(pool, SAT_FATAL, "susetags: bad =Shr line: %s\n", line + 6); + exit(1); + } + name = str2id(pool, sp[0], 1); + evr = makeevr(pool, join2(sp[1], "-", sp[2])); + arch = str2id(pool, sp[3], 1); + if (last_found_pack >= pd.nshare) + { + pd.share_with = sat_realloc2(pd.share_with, last_found_pack + 256, sizeof(*pd.share_with)); + memset(pd.share_with + pd.nshare, 0, (last_found_pack + 256 - pd.nshare) * sizeof(*pd.share_with)); + pd.nshare = last_found_pack + 256; + } + pd.share_with[last_found_pack].name = name; + pd.share_with[last_found_pack].evr = evr; + pd.share_with[last_found_pack].arch = arch; + if ((flags & SUSETAGS_RECORD_SHARES) != 0) + { + if (s->name == name) + repodata_set_void(data, handle, SUSETAGS_SHARE_NAME); + else + repodata_set_id(data, handle, SUSETAGS_SHARE_NAME, name); + if (s->evr == evr) + repodata_set_void(data, handle, SUSETAGS_SHARE_EVR); + else + repodata_set_id(data, handle, SUSETAGS_SHARE_EVR, evr); + if (s->arch == arch) + repodata_set_void(data, handle, SUSETAGS_SHARE_ARCH); + else + repodata_set_id(data, handle, SUSETAGS_SHARE_ARCH, arch); + } + continue; + } case CTAG('=', 'D', 'i', 'r'): add_dirline(&pd, line + 6); continue; @@ -922,7 +1017,6 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int if (pd.nshare) { int i, last_found; - last_found = 0; Map keyidmap; map_init(&keyidmap, data->nkeys); @@ -939,41 +1033,34 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int continue; if (keyname == SOLVABLE_PKGID || keyname == SOLVABLE_HDRID || keyname == SOLVABLE_LEADSIGID) continue; + if (keyname == SUSETAGS_SHARE_NAME || keyname == SUSETAGS_SHARE_EVR || keyname == SUSETAGS_SHARE_ARCH) + continue; MAPSET(&keyidmap, i); } + last_found = 0; for (i = 0; i < pd.nshare; i++) - if (pd.share_with[i]) - { - if (split(pd.share_with[i], sp, 5) != 4) - { - pool_debug(pool, SAT_FATAL, "susetags: bad =Shr line: %s\n", pd.share_with[i]); - exit(1); - } - - Id name = str2id(pool, sp[0], 1); - Id evr = makeevr(pool, join2(sp[1], "-", sp[2])); - Id arch = str2id(pool, sp[3], 1); - unsigned n, nn; - Solvable *found = 0; - for (n = repo->start, nn = repo->start + last_found; - n < repo->end; n++, nn++) - { - if (nn >= repo->end) - nn = repo->start; - found = pool->solvables + nn; - if (found->repo == repo - && found->name == name - && found->evr == evr - && found->arch == arch) - { - last_found = nn - repo->start; - break; - } - } - if (n != repo->end) - repodata_merge_some_attrs(data, repo->start + i, repo->start + last_found, &keyidmap, 0); - free(pd.share_with[i]); - } + { + unsigned n, nn; + Solvable *found = 0; + if (!pd.share_with[i].name) + continue; + for (n = repo->start, nn = repo->start + last_found; n < repo->end; n++, nn++) + { + if (nn >= repo->end) + nn = repo->start; + found = pool->solvables + nn; + if (found->repo == repo + && found->name == pd.share_with[i].name + && found->evr == pd.share_with[i].evr + && found->arch == pd.share_with[i].arch) + { + last_found = nn - repo->start; + break; + } + } + if (n != repo->end) + repodata_merge_some_attrs(data, repo->start + i, repo->start + last_found, &keyidmap, 0); + } free(pd.share_with); map_free(&keyidmap); } diff --git a/ext/repo_susetags.h b/ext/repo_susetags.h index f922dbf6..975622ed 100644 --- a/ext/repo_susetags.h +++ b/ext/repo_susetags.h @@ -10,5 +10,6 @@ */ #define SUSETAGS_EXTEND (1 << 9) +#define SUSETAGS_RECORD_SHARES (1 << 10) extern void repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int flags); diff --git a/src/knownid.h b/src/knownid.h index 1c322b77..7757ae0b 100644 --- a/src/knownid.h +++ b/src/knownid.h @@ -236,6 +236,10 @@ KNOWNID(PUBKEY_SIGNATURES, "pubkey:signatures"), KNOWNID(REPOSITORY_TOOLVERSION, "repository:toolversion"), KNOWNID(REPOSITORY_REPOID, "repository:repoid"), +KNOWNID(SUSETAGS_SHARE_NAME, "susetags:share:name"), +KNOWNID(SUSETAGS_SHARE_EVR, "susetags:share:evr"), +KNOWNID(SUSETAGS_SHARE_ARCH, "susetags:share:arch"), + KNOWNID(ID_NUM_INTERNAL, 0) #ifdef KNOWNID_INITIALIZE