ref: refs/heads/master
commit 999f54c0ad876830176f376f60d0770121a7e13b
Author: Michael Schroeder
Date: Mon Jun 22 11:25:45 2009 +0200
- add rpm_installedrpmdbids
- fix memleaks
---
tools/pool_fileconflicts.c | 37 +++++++++---
tools/repo_rpmdb.c | 140 +++++++++++++++++++++++++++++++++++++++-----
tools/repo_rpmdb.h | 5 +-
3 files changed, 158 insertions(+), 24 deletions(-)
diff --git a/tools/pool_fileconflicts.c b/tools/pool_fileconflicts.c
index e14d5c4..1858df4 100644
--- a/tools/pool_fileconflicts.c
+++ b/tools/pool_fileconflicts.c
@@ -21,6 +21,9 @@ struct cbdata {
Hashval *dirmap;
Hashmask dirmapn;
unsigned int dirmapused;
+ int dirconflicts;
+
+ Map idxmap;
Hashval idx;
unsigned int hx;
@@ -64,7 +67,7 @@ doublehash(Hashval *map, Hashmask *mapnp)
}
static void
-finddirs_cb(void *cbdatav, char *fn, int fmode, char *md5)
+finddirs_cb(void *cbdatav, const char *fn, int fmode, const char *md5)
{
struct cbdata *cbdata = cbdatav;
Hashmask h, hh, hx, qx;
@@ -99,7 +102,12 @@ finddirs_cb(void *cbdatav, char *fn, int fmode, char *md5)
if (cbdata->dirmap[2 * h + 1] == idx)
return;
/* found a conflict, this dir is used in multiple packages */
- cbdata->dirmap[2 * h + 1] = -1;
+ if (cbdata->dirmap[2 * h + 1] != -1)
+ {
+ cbdata->dirmap[2 * h + 1] = -1;
+ cbdata->dirconflicts++;
+ }
+ MAPSET(&cbdata->idxmap, idx);
}
static inline int
@@ -121,7 +129,7 @@ isindirmap(struct cbdata *cbdata, Hashmask hx)
}
static void
-findfileconflicts_cb(void *cbdatav, char *fn, int fmode, char *md5)
+findfileconflicts_cb(void *cbdatav, const char *fn, int fmode, const char *md5)
{
struct cbdata *cbdata = cbdatav;
int isdir = S_ISDIR(fmode);
@@ -201,7 +209,7 @@ addfilesspace(struct cbdata *cbdata, unsigned char *data, int len)
}
static void
-findfileconflicts2_cb(void *cbdatav, char *fn, int fmode, char *md5)
+findfileconflicts2_cb(void *cbdatav, const char *fn, int fmode, const char *md5)
{
struct cbdata *cbdata = cbdatav;
unsigned int hx = strhash(fn);
@@ -250,11 +258,12 @@ static int conflicts_cmp(const void *ap, const void *bp, void *dp)
int
pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, void *(*handle_cb)(Pool *, Id, void *) , void *handle_cbdata)
{
- int i, j, cflmapn;
+ int i, j, cflmapn, idxmapset;
unsigned int hx;
struct cbdata cbdata;
unsigned int now, start;
void *handle;
+ Id p;
queue_empty(conflicts);
if (!pkgs->count)
@@ -269,6 +278,8 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
queue_init(&cbdata.lookat);
queue_init(&cbdata.lookat_dir);
queue_init(&cbdata.files);
+ map_init(&cbdata.idxmap, pkgs->count);
+
if (cutoff <= 0)
cutoff = pkgs->count;
@@ -282,20 +293,24 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
cbdata.dirmap = sat_calloc(cflmapn, 2 * sizeof(Id));
cbdata.dirmapn = cflmapn - 1; /* make it a mask */
cbdata.create = 1;
+ idxmapset = 0;
for (i = 0; i < pkgs->count; i++)
{
- Id p = pkgs->elements[i];
+ p = pkgs->elements[i];
cbdata.idx = i;
if (i == cutoff)
cbdata.create = 0;
handle = (*handle_cb)(pool, p, handle_cbdata);
if (handle)
rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_ONLYDIRS, finddirs_cb, &cbdata);
+ if (MAPTST(&cbdata.idxmap, i))
+ idxmapset++;
}
POOL_DEBUG(SAT_DEBUG_STATS, "dirmap size: %d used %d\n", cbdata.dirmapn + 1, cbdata.dirmapused);
POOL_DEBUG(SAT_DEBUG_STATS, "dirmap memory usage: %d K\n", (cbdata.dirmapn + 1) * 2 * (int)sizeof(Id) / 1024);
POOL_DEBUG(SAT_DEBUG_STATS, "dirmap creation took %d ms\n", sat_timems(now));
+ POOL_DEBUG(SAT_DEBUG_STATS, "dir conflicts found: %d, idxmap %d of %d\n", cbdata.dirconflicts, idxmapset, pkgs->count);
/* second pass: scan files */
now = sat_timems(0);
@@ -307,7 +322,9 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
cbdata.create = 1;
for (i = 0; i < pkgs->count; i++)
{
- Id p = pkgs->elements[i];
+ if (!MAPTST(&cbdata.idxmap, i))
+ continue;
+ p = pkgs->elements[i];
cbdata.idx = i;
if (i == cutoff)
cbdata.create = 0;
@@ -326,6 +343,7 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
cbdata.cflmap = sat_free(cbdata.cflmap);
cbdata.cflmapn = 0;
cbdata.cflmapused = 0;
+ map_free(&cbdata.idxmap);
now = sat_timems(0);
POOL_DEBUG(SAT_DEBUG_STATS, "lookat_dir size: %d\n", cbdata.lookat_dir.count);
@@ -348,8 +366,7 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
{
int pend, ii, jj;
int pidx = cbdata.lookat.elements[i + 1];
- Id p = pkgs->elements[pidx];
-
+ p = pkgs->elements[pidx];
hx = cbdata.lookat.elements[i];
if (cbdata.lookat.elements[i + 2] != hx)
continue; /* no package left */
@@ -393,6 +410,8 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
}
cbdata.filesspace = sat_free(cbdata.filesspace);
cbdata.filesspacen = 0;
+ queue_free(&cbdata.lookat);
+ queue_free(&cbdata.files);
POOL_DEBUG(SAT_DEBUG_STATS, "candidate check took %d ms\n", sat_timems(now));
if (conflicts->count > 5)
sat_sort(conflicts->elements, conflicts->count / 5, 5 * sizeof(Id), conflicts_cmp, pool);
diff --git a/tools/repo_rpmdb.c b/tools/repo_rpmdb.c
index ddb6b68..826fa13 100644
--- a/tools/repo_rpmdb.c
+++ b/tools/repo_rpmdb.c
@@ -32,6 +32,7 @@
#include "repo.h"
#include "hash.h"
#include "util.h"
+#include "queue.h"
#include "repo_rpmdb.h"
#define RPMDB_COOKIE_VERSION 2
@@ -977,6 +978,8 @@ copydeps(Pool *pool, Repo *repo, Offset fromoff, Repo *fromrepo)
return ido;
}
+#define COPYDIR_DIRCACHE_SIZE 512
+
static Id copydir_complex(Pool *pool, Repodata *data, Stringpool *fromspool, Repodata *fromdata, Id did, Id *cache);
static inline Id
@@ -1201,7 +1204,7 @@ count_headers(const char *rootdir, DB_ENV *dbenv)
}
if (db->open(db, 0, "Name", 0, DB_UNKNOWN, DB_RDONLY, 0664))
{
- perror("db->open var/lib/rpm/Name");
+ perror("db->open Name index");
exit(1);
}
if (db->get_byteswapped(db, &byteswapped))
@@ -1287,11 +1290,6 @@ repo_add_rpmdb(Repo *repo, Repo *ref, const char *rootdir, int flags)
perror("dbenv open");
exit(1);
}
- if (db_create(&db, dbenv, 0))
- {
- perror("db_create");
- exit(1);
- }
/* XXX: should get ro lock of Packages database! */
snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm/Packages", rootdir);
@@ -1311,9 +1309,14 @@ repo_add_rpmdb(Repo *repo, Repo *ref, const char *rootdir, int flags)
if ((flags & RPMDB_REPORT_PROGRESS) != 0)
count = count_headers(rootdir, dbenv);
+ if (db_create(&db, dbenv, 0))
+ {
+ perror("db_create");
+ exit(1);
+ }
if (db->open(db, 0, "Packages", 0, DB_UNKNOWN, DB_RDONLY, 0664))
{
- perror("db->open var/lib/rpm/Packages");
+ perror("db->open Packages index");
exit(1);
}
if (db->get_byteswapped(db, &byteswapped))
@@ -1425,12 +1428,17 @@ repo_add_rpmdb(Repo *repo, Repo *ref, const char *rootdir, int flags)
}
else
{
- Id dircache[512];
+ Id dircache[COPYDIR_DIRCACHE_SIZE]; /* see copydir */
memset(dircache, 0, sizeof(dircache));
+ if (db_create(&db, dbenv, 0))
+ {
+ perror("db_create");
+ exit(1);
+ }
if (db->open(db, 0, "Name", 0, DB_UNKNOWN, DB_RDONLY, 0664))
{
- perror("db->open var/lib/rpm/Name");
+ perror("db->open Name index");
exit(1);
}
if (db->get_byteswapped(db, &byteswapped))
@@ -1804,14 +1812,16 @@ linkhash(const char *lt, char *hash)
}
void
-rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, char *, int, char *), void *cbdata)
+rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *, int, const char *), void *cbdata)
{
RpmHead *rpmhead = rpmhandle;
char **bn;
char **dn;
char **md = 0;
char **lt = 0;
- unsigned int *di;
+ unsigned int *di, diidx;
+ unsigned int lastdir;
+ int lastdirl;
unsigned int *fm;
int cnt, dcnt, cnt2;
int i, l1, l;
@@ -1865,11 +1875,14 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, char *, int,
return;
}
}
+ lastdir = dcnt;
+ lastdirl = 0;
for (i = 0; i < cnt; i++)
{
- if (di[i] >= dcnt)
+ diidx = di[i];
+ if (diidx >= dcnt)
continue;
- l1 = strlen(dn[di[i]]);
+ l1 = lastdir == diidx ? lastdirl : strlen(dn[diidx]);
if (l1 == 0)
continue;
l = l1 + strlen(bn[i]) + 1;
@@ -1878,7 +1891,12 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, char *, int,
spacen = l + 16;
space = sat_realloc(space, spacen);
}
- strcpy(space, dn[di[i]]);
+ if (lastdir != diidx)
+ {
+ strcpy(space, dn[diidx]);
+ lastdir = diidx;
+ lastdirl = l1;
+ }
strcpy(space + l1, bn[i]);
if (md)
{
@@ -1903,6 +1921,7 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, char *, int,
}
(*cb)(cbdata, space, fm[i], md5p);
}
+ sat_free(space);
sat_free(lt);
sat_free(md);
sat_free(fm);
@@ -1922,6 +1941,99 @@ struct rpm_by_state {
int byteswapped;
};
+int
+rpm_installedrpmdbids(const char *rootdir, Queue *rpmdbidq)
+{
+ char dbpath[PATH_MAX];
+ DB_ENV *dbenv = 0;
+ DB *db = 0;
+ DBC *dbc = 0;
+ int byteswapped;
+ DBT dbkey;
+ DBT dbdata;
+ Id rpmdbid;
+ unsigned char *dp;
+ int dl, cnt;
+
+ if (rpmdbidq)
+ queue_empty(rpmdbidq);
+ cnt = 0;
+
+ if (db_env_create(&dbenv, 0))
+ {
+ perror("db_env_create");
+ return 0;
+ }
+ snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm", rootdir ? rootdir : "");
+#ifdef FEDORA
+ if (dbenv->open(dbenv, dbpath, DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL, 0))
+#else
+ if (dbenv->open(dbenv, dbpath, DB_CREATE|DB_PRIVATE|DB_INIT_MPOOL, 0))
+#endif
+ {
+ perror("dbenv open");
+ dbenv->close(dbenv, 0);
+ return 0;
+ }
+ if (db_create(&db, dbenv, 0))
+ {
+ perror("db_create");
+ dbenv->close(dbenv, 0);
+ return 0;
+ }
+ if (db->open(db, 0, "Name", 0, DB_UNKNOWN, DB_RDONLY, 0664))
+ {
+ perror("db->open Name index");
+ db->close(db, 0);
+ dbenv->close(dbenv, 0);
+ return 0;
+ }
+ if (db->get_byteswapped(db, &byteswapped))
+ {
+ perror("db->get_byteswapped");
+ db->close(db, 0);
+ dbenv->close(dbenv, 0);
+ return 0;
+ }
+ if (db->cursor(db, NULL, &dbc, 0))
+ {
+ perror("db->cursor");
+ db->close(db, 0);
+ dbenv->close(dbenv, 0);
+ return 0;
+ }
+ memset(&dbkey, 0, sizeof(dbkey));
+ memset(&dbdata, 0, sizeof(dbdata));
+ while (dbc->c_get(dbc, &dbkey, &dbdata, DB_NEXT) == 0)
+ {
+ if (dbkey.size == 10 && !memcmp(dbkey.data, "gpg-pubkey", 10))
+ continue;
+ dl = dbdata.size;
+ dp = dbdata.data;
+ while(dl >= 8)
+ {
+ if (byteswapped)
+ {
+ ((char *)&rpmdbid)[0] = dp[3];
+ ((char *)&rpmdbid)[1] = dp[2];
+ ((char *)&rpmdbid)[2] = dp[1];
+ ((char *)&rpmdbid)[3] = dp[0];
+ }
+ else
+ memcpy((char *)&rpmdbid, dp, 4);
+ if (rpmdbidq)
+ queue_push(rpmdbidq, rpmdbid);
+ cnt++;
+ dp += 8;
+ dl -= 8;
+ }
+ }
+ dbc->c_close(dbc);
+ db->close(db, 0);
+ dbenv->close(dbenv, 0);
+ return cnt;
+}
+
void *
rpm_byrpmdbid(Id rpmdbid, const char *rootdir, void **statep)
{
diff --git a/tools/repo_rpmdb.h b/tools/repo_rpmdb.h
index 6c907c7..3e80302 100644
--- a/tools/repo_rpmdb.h
+++ b/tools/repo_rpmdb.h
@@ -5,6 +5,8 @@
* for further information
*/
+#include "queue.h"
+
extern void repo_add_rpmdb(Repo *repo, Repo *ref, const char *rootdir, int flags);
extern void repo_add_rpms(Repo *repo, const char **rpms, int nrpms, int flags);
@@ -15,4 +17,5 @@ extern void repo_add_rpms(Repo *repo, const char **rpms, int nrpms, int flags);
void *rpm_byrpmdbid(Id rpmdbid, const char *rootdir, void **statep);
void *rpm_byfp(FILE *fp, const char *name, void **statep);
-void rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, char *, int, char *), void *cbdata);
+void rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *, int, const char *), void *cbdata);
+int rpm_installedrpmdbids(const char *rootdir, Queue *rpmdbidq);
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org