Skip to content

Commit

Permalink
add repo_add_rpmdb_reffp to easily add rpmdb content when there is an…
Browse files Browse the repository at this point in the history
… old solv file
  • Loading branch information
mlschroe committed Apr 23, 2013
1 parent 7ea7526 commit 843dc7e
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 127 deletions.
20 changes: 5 additions & 15 deletions examples/solv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1723,8 +1723,7 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos)
else
{
#if defined(ENABLE_RPMDB) && (defined(SUSE) || defined(FEDORA))
FILE *ofp;
Repo *ref = 0;
FILE *ofp = 0;
#endif
printf(" reading\n");

Expand All @@ -1736,23 +1735,14 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos)
exit(1);
}
# endif
if ((ofp = fopen(calccachepath(repo, 0), "r")) != 0)
{
ref = repo_create(pool, "@System.old");
if (repo_add_solv(ref, ofp, 0))
{
repo_free(ref, 1);
ref = 0;
}
fclose(ofp);
}
if (repo_add_rpmdb(repo, ref, REPO_REUSE_REPODATA | REPO_USE_ROOTDIR))
ofp = fopen(calccachepath(repo, 0), "r");
if (repo_add_rpmdb_reffp(repo, ofp, REPO_REUSE_REPODATA | REPO_USE_ROOTDIR))
{
fprintf(stderr, "installed db: %s\n", pool_errstr(pool));
exit(1);
}
if (ref)
repo_free(ref, 1);
if (ofp)
fclose(ofp);
#endif
#if defined(ENABLE_DEBIAN) && defined(DEBIAN)
if (repo_add_debdb(repo, REPO_REUSE_REPODATA | REPO_USE_ROOTDIR))
Expand Down
1 change: 1 addition & 0 deletions ext/libsolvext.ver
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ SOLV_1.0 {
repo_add_rpm_handle;
repo_add_rpmdb;
repo_add_rpmdb_pubkeys;
repo_add_rpmdb_reffp;
repo_add_rpmmd;
repo_add_susetags;
repo_add_updateinfoxml;
Expand Down
135 changes: 60 additions & 75 deletions ext/repo_rpmdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "queue.h"
#include "chksum.h"
#include "repo_rpmdb.h"
#include "repo_solv.h"

/* 3: added triggers */
/* 4: fixed triggers */
Expand Down Expand Up @@ -1355,29 +1356,12 @@ count_headers(Pool *pool, const char *rootdir, DB_ENV *dbenv)

/******************************************************************/

static Id
copyreldep(Pool *pool, Pool *frompool, Id id)
{
Reldep *rd = GETRELDEP(frompool, id);
Id name = rd->name, evr = rd->evr;
if (ISRELDEP(name))
name = copyreldep(pool, frompool, name);
else
name = pool_str2id(pool, pool_id2str(frompool, name), 1);
if (ISRELDEP(evr))
evr = copyreldep(pool, frompool, evr);
else
evr = pool_str2id(pool, pool_id2str(frompool, evr), 1);
return pool_rel2id(pool, name, evr, rd->flags, 1);
}

static Offset
copydeps(Pool *pool, Repo *repo, Offset fromoff, Repo *fromrepo)
{
int cc;
Id id, *ida, *from;
Id *ida, *from;
Offset ido;
Pool *frompool = fromrepo->pool;

if (!fromoff)
return 0;
Expand All @@ -1388,46 +1372,32 @@ copydeps(Pool *pool, Repo *repo, Offset fromoff, Repo *fromrepo)
return 0;
ido = repo_reserve_ids(repo, 0, cc);
ida = repo->idarraydata + ido;
if (frompool && pool != frompool)
{
while (*from)
{
id = *from++;
if (ISRELDEP(id))
id = copyreldep(pool, frompool, id);
else
id = pool_str2id(pool, pool_id2str(frompool, id), 1);
*ida++ = id;
}
*ida = 0;
}
else
memcpy(ida, from, (cc + 1) * sizeof(Id));
memcpy(ida, from, (cc + 1) * sizeof(Id));
repo->idarraysize += cc + 1;
return ido;
}

#define COPYDIR_DIRCACHE_SIZE 512

static Id copydir_complex(Pool *pool, Repodata *data, Stringpool *fromspool, Repodata *fromdata, Id did, Id *cache);
static Id copydir_complex(Pool *pool, Repodata *data, Repodata *fromdata, Id did, Id *cache);

static inline Id
copydir(Pool *pool, Repodata *data, Stringpool *fromspool, Repodata *fromdata, Id did, Id *cache)
copydir(Pool *pool, Repodata *data, Repodata *fromdata, Id did, Id *cache)
{
if (cache && cache[did & 255] == did)
return cache[(did & 255) + 256];
return copydir_complex(pool, data, fromspool, fromdata, did, cache);
return copydir_complex(pool, data, fromdata, did, cache);
}

static Id
copydir_complex(Pool *pool, Repodata *data, Stringpool *fromspool, Repodata *fromdata, Id did, Id *cache)
copydir_complex(Pool *pool, Repodata *data, Repodata *fromdata, Id did, Id *cache)
{
Id parent = dirpool_parent(&fromdata->dirpool, did);
Id compid = dirpool_compid(&fromdata->dirpool, did);
if (parent)
parent = copydir(pool, data, fromspool, fromdata, parent, cache);
if (fromspool != &pool->ss)
compid = pool_str2id(pool, stringpool_id2str(fromspool, compid), 1);
parent = copydir(pool, data, fromdata, parent, cache);
if (fromdata->localpool)
compid = repodata_globalize_id(fromdata, compid, 1);
compid = dirpool_add_dir(&data->dirpool, parent, compid, 1);
if (cache)
{
Expand All @@ -1451,26 +1421,18 @@ solvable_copy_cb(void *vcbdata, Solvable *r, Repodata *fromdata, Repokey *key, K
Id id, keyname;
Repodata *data = cbdata->data;
Id handle = cbdata->handle;
Pool *pool = data->repo->pool, *frompool = fromdata->repo->pool;
Stringpool *fromspool = fromdata->localpool ? &fromdata->spool : &frompool->ss;
Pool *pool = data->repo->pool;

keyname = key->name;
if (keyname >= ID_NUM_INTERNAL && pool != frompool)
keyname = pool_str2id(pool, pool_id2str(frompool, keyname), 1);
switch(key->type)
{
case REPOKEY_TYPE_ID:
case REPOKEY_TYPE_CONSTANTID:
case REPOKEY_TYPE_IDARRAY: /* used for triggers */
id = kv->id;
if (fromdata->localpool)
id = repodata_globalize_id(fromdata, id, 1);
assert(!data->localpool); /* implement me! */
if (pool != frompool || fromdata->localpool)
{
if (ISRELDEP(id))
id = copyreldep(pool, frompool, id);
else
id = pool_str2id(pool, stringpool_id2str(fromspool, id), 1);
}
if (key->type == REPOKEY_TYPE_ID)
repodata_set_id(data, handle, keyname, id);
else if (key->type == REPOKEY_TYPE_CONSTANTID)
Expand All @@ -1492,14 +1454,14 @@ solvable_copy_cb(void *vcbdata, Solvable *r, Repodata *fromdata, Repokey *key, K
break;
case REPOKEY_TYPE_DIRNUMNUMARRAY:
id = kv->id;
id = copydir(pool, data, fromdata, id, cbdata->dircache);
assert(!data->localpool); /* implement me! */
id = copydir(pool, data, fromspool, fromdata, id, cbdata->dircache);
repodata_add_dirnumnum(data, handle, keyname, id, kv->num, kv->num2);
break;
case REPOKEY_TYPE_DIRSTRARRAY:
id = kv->id;
id = copydir(pool, data, fromdata, id, cbdata->dircache);
assert(!data->localpool); /* implement me! */
id = copydir(pool, data, fromspool, fromdata, id, cbdata->dircache);
repodata_add_dirstr(data, handle, keyname, id, kv->str);
break;
case REPOKEY_TYPE_FLEXARRAY:
Expand Down Expand Up @@ -1528,29 +1490,15 @@ static void
solvable_copy(Solvable *s, Solvable *r, Repodata *data, Id *dircache)
{
Repo *repo = s->repo;
Repo *fromrepo = r->repo;
Pool *pool = repo->pool;
Repo *fromrepo = r->repo;
struct solvable_copy_cbdata cbdata;

/* copy solvable data */
if (pool == fromrepo->pool)
{
s->name = r->name;
s->evr = r->evr;
s->arch = r->arch;
s->vendor = r->vendor;
}
else
{
if (r->name)
s->name = pool_str2id(pool, pool_id2str(fromrepo->pool, r->name), 1);
if (r->evr)
s->evr = pool_str2id(pool, pool_id2str(fromrepo->pool, r->evr), 1);
if (r->arch)
s->arch = pool_str2id(pool, pool_id2str(fromrepo->pool, r->arch), 1);
if (r->vendor)
s->vendor = pool_str2id(pool, pool_id2str(fromrepo->pool, r->vendor), 1);
}
s->name = r->name;
s->evr = r->evr;
s->arch = r->arch;
s->vendor = r->vendor;
s->provides = copydeps(pool, repo, r->provides, fromrepo);
s->requires = copydeps(pool, repo, r->requires, fromrepo);
s->conflicts = copydeps(pool, repo, r->conflicts, fromrepo);
Expand Down Expand Up @@ -1655,8 +1603,12 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)

data = repo_add_repodata(repo, flags);

if (ref && !(ref->nsolvables && ref->rpmdbid))
ref = 0;
if (ref && !(ref->nsolvables && ref->rpmdbid && ref->pool == repo->pool))
{
if ((flags & RPMDB_EMPTY_REFREPO) != 0)
repo_empty(ref, 1);
ref = 0;
}

if (flags & REPO_USE_ROOTDIR)
rootdir = pool_get_rootdir(pool);
Expand All @@ -1682,6 +1634,8 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
Id dbid;
DBC *dbc = 0;

if (ref && (flags & RPMDB_EMPTY_REFREPO) != 0)
repo_empty(ref, 1); /* get it out of the way */
if ((flags & RPMDB_REPORT_PROGRESS) != 0)
count = count_headers(pool, rootdir, state.dbenv);
if (!openpkgdb(&state))
Expand Down Expand Up @@ -1820,7 +1774,10 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
}
}

s = pool_id2solvable(pool, repo_add_solvable_block(repo, nentries));
if (ref && (flags & RPMDB_EMPTY_REFREPO) != 0)
s = pool_id2solvable(pool, repo_add_solvable_block_before(repo, nentries, ref));
else
s = pool_id2solvable(pool, repo_add_solvable_block(repo, nentries));
if (!repo->rpmdbid)
repo->rpmdbid = repo_sidedata_create(repo, sizeof(Id));

Expand Down Expand Up @@ -1871,6 +1828,8 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
solv_free(entries);
solv_free(namedata);
solv_free(refhash);
if (ref && (flags & RPMDB_EMPTY_REFREPO) != 0)
repo_empty(ref, 1);
}

freestate(&state);
Expand All @@ -1884,6 +1843,32 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
return 0;
}

int
repo_add_rpmdb_reffp(Repo *repo, FILE *fp, int flags)
{
int res;
Repo *ref = 0;

if (!fp)
return repo_add_rpmdb(repo, 0, flags);
ref = repo_create(repo->pool, "add_rpmdb_reffp");
if (repo_add_solv(ref, fp, 0) != 0)
{
repo_free(ref, 1);
ref = 0;
}
if (ref && ref->start == ref->end)
{
repo_free(ref, 1);
ref = 0;
}
if (ref)
repo_disable_paging(ref);
res = repo_add_rpmdb(repo, ref, flags | RPMDB_EMPTY_REFREPO);
if (ref)
repo_free(ref, 1);
return res;
}

static inline unsigned int
getu32(const unsigned char *dp)
Expand Down
5 changes: 4 additions & 1 deletion ext/repo_rpmdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
struct headerToken_s;

extern int repo_add_rpmdb(Repo *repo, Repo *ref, int flags);
extern int repo_add_rpmdb_reffp(Repo *repo, FILE *reffp, int flags);
extern Id repo_add_rpm(Repo *repo, const char *rpm, int flags);

#define RPMDB_REPORT_PROGRESS (1 << 8)
Expand All @@ -22,7 +23,9 @@ extern Id repo_add_rpm(Repo *repo, const char *rpm, int flags);
#define RPM_ADD_TRIGGERS (1 << 14)
#define RPM_ADD_WITH_HDRID (1 << 15)
#define RPM_ADD_WITH_LEADSIGID (1 << 16)
#define RPM_ADD_WITH_CHANGELOG (1 << 17)
#define RPM_ADD_WITH_CHANGELOG (1 << 17)

#define RPMDB_EMPTY_REFREPO (1 << 30) /* internal */

#define RPM_ITERATE_FILELIST_ONLYDIRS (1 << 0)
#define RPM_ITERATE_FILELIST_WITHMD5 (1 << 1)
Expand Down
1 change: 1 addition & 0 deletions src/libsolv.ver
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ SOLV_1.0 {
repo_add_solv;
repo_add_solvable;
repo_add_solvable_block;
repo_add_solvable_block_before;
repo_addid;
repo_addid_dep;
repo_create;
Expand Down
48 changes: 48 additions & 0 deletions src/repo.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,54 @@ repo_free_solvable_block(Repo *repo, Id start, int count, int reuseids)
}
}

/* specialized version of repo_add_solvable_block that inserts the new solvable
* block before the indicated repo, which gets relocated.
* used in repo_add_rpmdb
*/
Id
repo_add_solvable_block_before(Repo *repo, int count, Repo *beforerepo)
{
Pool *pool = repo->pool;
Id p;
Solvable *s;
Repodata *data;
int i;

if (!count || !beforerepo || beforerepo->end != pool->nsolvables || beforerepo->start == beforerepo->end)
return repo_add_solvable_block(repo, count);
p = beforerepo->start;
/* make sure all solvables belong to beforerepo */
for (i = p, s = pool->solvables + i; i < beforerepo->end; i++, s++)
if (s->repo && s->repo != beforerepo)
return repo_add_solvable_block(repo, count);
/* now move beforerepo to back */
pool_add_solvable_block(pool, count); /* must return beforerepo->end! */
memmove(pool->solvables + p + count, pool->solvables + p, (beforerepo->end - p) * sizeof(Solvable));
memset(pool->solvables + p, 0, sizeof(Solvable) * count);
/* adapt repodata */
FOR_REPODATAS(beforerepo, i, data)
{
if (data->start < p)
continue;
data->start += count;
data->end += count;
}
beforerepo->start += count;
beforerepo->end += count;
/* we now have count free solvables at id p */
/* warning: sidedata must be extended before adapting start/end */
if (repo->rpmdbid)
repo->rpmdbid = (Id *)repo_sidedata_extend(repo, repo->rpmdbid, sizeof(Id), p, count);
if (p < repo->start)
repo->start = p;
if (p + count > repo->end)
repo->end = p + count;
repo->nsolvables += count;
for (s = pool->solvables + p; count--; s++)
s->repo = repo;
return p;
}


/* repository sidedata is solvable data allocated on demand.
* It is used for data that is normally not present
Expand Down
1 change: 1 addition & 0 deletions src/repo.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ extern void repo_free_solvable(Repo *repo, Id p, int reuseids);
extern void repo_free_solvable_block(Repo *repo, Id start, int count, int reuseids);
extern void *repo_sidedata_create(Repo *repo, size_t size);
extern void *repo_sidedata_extend(Repo *repo, void *b, size_t size, Id p, int count);
extern Id repo_add_solvable_block_before(Repo *repo, int count, Repo *beforerepo);

extern Offset repo_addid(Repo *repo, Offset olddeps, Id id);
extern Offset repo_addid_dep(Repo *repo, Offset olddeps, Id id, Id marker);
Expand Down
Loading

0 comments on commit 843dc7e

Please sign in to comment.