From b19f33c9b5d68bdabe49864522d55e8551672e6b Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Tue, 18 Sep 2018 14:49:57 +0200 Subject: [PATCH] Add repodata_translate_dir method This translates a dir id from one repodata to another. Change repo_rpmdb to use it when copying solvables. --- ext/repo_rpmdb.c | 47 +++++---------------------------------------- src/libsolv.ver | 1 + src/repodata.c | 50 ++++++++++++++++++++++++++++++++++++++++-------- src/repodata.h | 22 +++++++++++++++++++++ 4 files changed, 70 insertions(+), 50 deletions(-) diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c index 3a5c114b..e01993ce 100644 --- a/ext/repo_rpmdb.c +++ b/ext/repo_rpmdb.c @@ -1385,44 +1385,6 @@ copydeps(Pool *pool, Repo *repo, Offset fromoff, Repo *fromrepo) return ido; } -#define COPYDIR_DIRCACHE_SIZE 512 - -static Id copydir_complex(Repodata *data, Repodata *fromdata, Id did, Id *cache); - -static inline Id -copydir(Repodata *data, Repodata *fromdata, Id did, Id *cache) -{ - if (cache && did && cache[did & 255] == did) - return cache[(did & 255) + 256]; - return copydir_complex(data, fromdata, did, cache); -} - -static Id -copydir_complex(Repodata *data, Repodata *fromdata, Id did, Id *cache) -{ - Id parent, compid; - if (!did) - { - /* make sure that the dirpool has an entry */ - if (!data->dirpool.ndirs) - dirpool_add_dir(&data->dirpool, 0, 0, 1); - return 0; - } - parent = dirpool_parent(&fromdata->dirpool, did); - compid = dirpool_compid(&fromdata->dirpool, did); - if (parent) - parent = copydir(data, fromdata, parent, cache); - if (data->localpool || fromdata->localpool) - compid = repodata_translate_id(data, fromdata, compid, 1); - compid = dirpool_add_dir(&data->dirpool, parent, compid, 1); - if (cache) - { - cache[did & 255] = did; - cache[(did & 255) + 256] = compid; - } - return compid; -} - struct solvable_copy_cbdata { Repodata *data; Id handle; @@ -1447,7 +1409,7 @@ solvable_copy_cb(void *vcbdata, Solvable *r, Repodata *fromdata, Repokey *key, K break; case REPOKEY_TYPE_DIRNUMNUMARRAY: case REPOKEY_TYPE_DIRSTRARRAY: - kv->id = copydir(data, fromdata, kv->id, data->repodataid == 1 ? cbdata->dircache : 0); + kv->id = repodata_translate_dir(data, fromdata, kv->id, 1, fromdata->repodataid == 1 ? cbdata->dircache : 0); break; case REPOKEY_TYPE_FLEXARRAY: if (kv->eof == 2) @@ -1732,7 +1694,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags) } else { - Id dircache[COPYDIR_DIRCACHE_SIZE]; /* see copydir */ + Id *dircache; Id *oldkeyskip = 0; struct rpmdbentry *entries = 0, *rp; int nentries = 0; @@ -1741,8 +1703,6 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags) Id id, *refhash; int res; - memset(dircache, 0, sizeof(dircache)); - /* get ids of installed rpms */ entries = getinstalledrpmdbids(&state, "Name", 0, &nentries, &namedata, flags & RPMDB_KEEP_GPG_PUBKEY); if (!entries) @@ -1797,6 +1757,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags) if (!repo->rpmdbid) repo->rpmdbid = repo_sidedata_create(repo, sizeof(Id)); + dircache = repodata_create_dirtranscache(data); for (i = 0, rp = entries; i < nentries; i++, rp++, s++) { Id dbid = rp->rpmdbid; @@ -1829,6 +1790,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags) solv_free(entries); solv_free(namedata); solv_free(refhash); + dircache = repodata_free_dirtranscache(dircache); return -1; } rpmhead2solv(pool, repo, data, s, state.rpmhead, flags | RPM_ADD_TRIGGERS); @@ -1840,6 +1802,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags) pool_debug(pool, SOLV_ERROR, "%%%% %d\n", done * 100 / count); } } + dircache = repodata_free_dirtranscache(dircache); solv_free(oldkeyskip); solv_free(entries); diff --git a/src/libsolv.ver b/src/libsolv.ver index 684f20fd..e6bff90c 100644 --- a/src/libsolv.ver +++ b/src/libsolv.ver @@ -240,6 +240,7 @@ SOLV_1.0 { repodata_str2dir; repodata_stringify; repodata_swap_attrs; + repodata_translate_dir_slow; repodata_translate_id; repodata_unset; repodata_unset_uninternalized; diff --git a/src/repodata.c b/src/repodata.c index 5e5cbe20..b4aa7147 100644 --- a/src/repodata.c +++ b/src/repodata.c @@ -889,18 +889,52 @@ repodata_localize_id(Repodata *data, Id id, int create) Id repodata_translate_id(Repodata *data, Repodata *fromdata, Id id, int create) { + const char *s; if (!id || !data || !fromdata) return id; - if (!data->localpool || !fromdata->localpool) + if (data == fromdata || (!data->localpool && !fromdata->localpool)) + return id; + if (fromdata->localpool) + s = stringpool_id2str(&fromdata->spool, id); + else + s = pool_id2str(data->repo->pool, id); + if (data->localpool) + return stringpool_str2id(&data->spool, s, create); + else + return pool_str2id(data->repo->pool, s, create); +} + +Id +repodata_translate_dir_slow(Repodata *data, Repodata *fromdata, Id dir, int create, Id *cache) +{ + Id parent, compid; + if (!dir) { - if (fromdata->localpool) - id = repodata_globalize_id(fromdata, id, create); - if (data->localpool) - id = repodata_localize_id(data, id, create); - return id; + /* make sure that the dirpool has an entry */ + if (create && !data->dirpool.ndirs) + dirpool_add_dir(&data->dirpool, 0, 0, create); + return 0; + } + parent = dirpool_parent(&fromdata->dirpool, dir); + if (parent) + { + if (!(parent = repodata_translate_dir(data, fromdata, parent, create, cache))) + return 0; + } + compid = dirpool_compid(&fromdata->dirpool, dir); + if (compid > 1 && (data->localpool || fromdata->localpool)) + { + if (!(compid = repodata_translate_id(data, fromdata, compid, create))) + return 0; + } + if (!(compid = dirpool_add_dir(&data->dirpool, parent, compid, create))) + return 0; + if (cache) + { + cache[(dir & 255) * 2] = dir; + cache[(dir & 255) * 2 + 1] = compid; } - /* localpool is set in both data and fromdata */ - return stringpool_str2id(&data->spool, stringpool_id2str(&fromdata->spool, id), create); + return compid; } /* uninternalized lookups */ diff --git a/src/repodata.h b/src/repodata.h index f13d7997..a6ecd967 100644 --- a/src/repodata.h +++ b/src/repodata.h @@ -314,6 +314,7 @@ void repodata_disable_paging(Repodata *data); Id repodata_globalize_id(Repodata *data, Id id, int create); Id repodata_localize_id(Repodata *data, Id id, int create); Id repodata_translate_id(Repodata *data, Repodata *fromdata, Id id, int create); +Id repodata_translate_dir_slow(Repodata *data, Repodata *fromdata, Id dir, int create, Id *cache); Id repodata_str2dir(Repodata *data, const char *dir, int create); const char *repodata_dir2str(Repodata *data, Id did, const char *suf); @@ -330,6 +331,27 @@ const unsigned char *repodata_lookup_bin_checksum_uninternalized(Repodata *data, /* stats */ unsigned int repodata_memused(Repodata *data); +static inline Id +repodata_translate_dir(Repodata *data, Repodata *fromdata, Id dir, int create, Id *cache) +{ + if (cache && dir && cache[(dir & 255) * 2] == dir) + return cache[(dir & 255) * 2 + 1]; + return repodata_translate_dir_slow(data, fromdata, dir, create, cache); +} + +static inline Id * +repodata_create_dirtranscache(Repodata *data) +{ + return solv_calloc(256, sizeof(Id) * 2); +} + +static inline Id * +repodata_free_dirtranscache(Id *cache) +{ + return solv_free(cache); +} + + #ifdef __cplusplus } #endif -- 2.47.2