diff options
author | Michael Schroeder <mls@suse.de> | 2013-04-10 15:47:18 +0200 |
---|---|---|
committer | Michael Schroeder <mls@suse.de> | 2013-04-10 15:47:18 +0200 |
commit | 261b19e87a1b5bdea9dfca450512ba2630ca0aa5 (patch) | |
tree | 69ee1e09b72d98c8f5d737cf7cdd78981236d593 /ext | |
parent | b309e4bde9b3ab0bfb29d38a4b4a81bbd31dc3d5 (diff) | |
download | libsolv-261b19e87a1b5bdea9dfca450512ba2630ca0aa5.tar.gz libsolv-261b19e87a1b5bdea9dfca450512ba2630ca0aa5.tar.bz2 libsolv-261b19e87a1b5bdea9dfca450512ba2630ca0aa5.zip |
improve iterate_filelist, it now calls the callback with a struct filelistinfo
This makes the code extensible, plus we can now pass things like
the diridx and the dirlen which can be used to speed up the
fileconflict code.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/pool_fileconflicts.c | 53 | ||||
-rw-r--r-- | ext/repo_rpmdb.c | 35 | ||||
-rw-r--r-- | ext/repo_rpmdb.h | 11 |
3 files changed, 67 insertions, 32 deletions
diff --git a/ext/pool_fileconflicts.c b/ext/pool_fileconflicts.c index 27e7ab8..37364ba 100644 --- a/ext/pool_fileconflicts.c +++ b/ext/pool_fileconflicts.c @@ -32,6 +32,9 @@ struct cbdata { Map idxmap; + unsigned int lastdiridx; /* last diridx we have seen */ + unsigned int lastdirhash; /* strhash of last dir we have seen */ + Id idx; /* index of package we're looking at */ Id hx; /* used in findfileconflicts2_cb, limit to files matching hx */ @@ -75,7 +78,7 @@ growhash(Hashtable map, Hashval *mapnp) } static void -finddirs_cb(void *cbdatav, const char *fn, int fmode, const char *md5) +finddirs_cb(void *cbdatav, const char *fn, struct filelistinfo *info) { struct cbdata *cbdata = cbdatav; Hashval h, hh; @@ -141,27 +144,32 @@ isindirmap(struct cbdata *cbdata, Id hx) } static void -findfileconflicts_cb(void *cbdatav, const char *fn, int fmode, const char *md5) +findfileconflicts_cb(void *cbdatav, const char *fn, struct filelistinfo *info) { struct cbdata *cbdata = cbdatav; - int isdir = S_ISDIR(fmode); - char *dp; + int isdir = S_ISDIR(info->mode); + const char *dp; Id idx, oidx; Id hx, qx; Hashval h, hh, dhx; idx = cbdata->idx; - dp = strrchr(fn, '/'); - if (!dp) + if (!info->dirlen) return; - dhx = strnhash(fn, dp + 1 - fn); + dp = fn + info->dirlen; + if (info->diridx != cbdata->lastdiridx) + { + cbdata->lastdiridx = info->diridx; + cbdata->lastdirhash = strnhash(fn, dp - fn); + } + dhx = cbdata->lastdirhash; #if 1 /* this mirrors the "if (!hx) hx = strlen(fn) + 1" in finddirs_cb */ - if (!isindirmap(cbdata, dhx ? dhx : dp + 1 - fn + 1)) + if (!isindirmap(cbdata, dhx ? dhx : dp - fn + 1)) return; #endif - hx = strhash_cont(dp + 1, dhx); + hx = strhash_cont(dp, dhx); if (!hx) hx = strlen(fn) + 1; @@ -221,19 +229,30 @@ addfilesspace(struct cbdata *cbdata, unsigned char *data, int len) } static void -findfileconflicts2_cb(void *cbdatav, const char *fn, int fmode, const char *md5) +findfileconflicts2_cb(void *cbdatav, const char *fn, struct filelistinfo *info) { struct cbdata *cbdata = cbdatav; - Hashval hx = strhash(fn); + Hashval hx; + const char *dp; char md5padded[34]; + if (!info->dirlen) + return; + dp = fn + info->dirlen; + if (info->diridx != cbdata->lastdiridx) + { + cbdata->lastdiridx = info->diridx; + cbdata->lastdirhash = strnhash(fn, dp - fn); + } + hx = cbdata->lastdirhash; + hx = strhash_cont(dp, hx); if (!hx) hx = strlen(fn) + 1; if ((Id)hx != cbdata->hx) return; - strncpy(md5padded, md5, 32); + strncpy(md5padded, info->digest, 32); md5padded[32] = 0; - md5padded[33] = fmode >> 24; + md5padded[33] = info->color; /* printf("%d, hx %x -> %s %d %s\n", cbdata->idx, hx, fn, fmode, md5); */ queue_push(&cbdata->files, cbdata->filesspacen); addfilesspace(cbdata, (unsigned char *)md5padded, 34); @@ -341,8 +360,10 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo if (i == cutoff) cbdata.create = 0; handle = (*handle_cb)(pool, p, handle_cbdata); - if (handle) - rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_NOGHOSTS, findfileconflicts_cb, &cbdata); + if (!handle) + continue; + cbdata.lastdiridx = -1; + rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_NOGHOSTS, findfileconflicts_cb, &cbdata); } POOL_DEBUG(SOLV_DEBUG_STATS, "filemap size: %d, used %d\n", cbdata.cflmapn + 1, cbdata.cflmapused); @@ -398,6 +419,7 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo handle = (*handle_cb)(pool, p, handle_cbdata); if (!handle) continue; + cbdata.lastdiridx = -1; rpm_iterate_filelist(handle, iterflags, findfileconflicts2_cb, &cbdata); pend = cbdata.files.count; @@ -411,6 +433,7 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo handle = (*handle_cb)(pool, q, handle_cbdata); if (!handle) continue; + cbdata.lastdiridx = -1; rpm_iterate_filelist(handle, iterflags, findfileconflicts2_cb, &cbdata); for (ii = 0; ii < pend; ii++) for (jj = pend; jj < cbdata.files.count; jj++) diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c index 727fc50..2e39a68 100644 --- a/ext/repo_rpmdb.c +++ b/ext/repo_rpmdb.c @@ -2056,14 +2056,11 @@ linkhash(const char *lt, char *hash) l = strlen(lt); while ((c = *str++) != 0) r += (r << 3) + c; - sprintf(hash, "%08x", r); - sprintf(hash + 8, "%08x", l); - sprintf(hash + 16, "%08x", 0); - sprintf(hash + 24, "%08x", 0); + sprintf(hash, "%08x%08x%08x%08x", r, l, 0, 0); } void -rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *, int, const char *), void *cbdata) +rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *, struct filelistinfo *), void *cbdata) { RpmHead *rpmhead = rpmhandle; char **bn; @@ -2080,7 +2077,8 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char * int i, l1, l; char *space = 0; int spacen = 0; - char md5[33], *md5p = 0; + char md5[33]; + struct filelistinfo info; dn = headstringarray(rpmhead, TAG_DIRNAMES, &dcnt); if (!dn) @@ -2088,7 +2086,7 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char * if ((flags & RPM_ITERATE_FILELIST_ONLYDIRS) != 0) { for (i = 0; i < dcnt; i++) - (*cb)(cbdata, dn[i], 0, (char *)0); + (*cb)(cbdata, dn[i], 0); solv_free(dn); return; } @@ -2159,6 +2157,7 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char * } lastdir = dcnt; lastdirl = 0; + memset(&info, 0, sizeof(info)); for (i = 0; i < cnt; i++) { if (ff && (ff[i] & FILEFLAG_GHOST) != 0) @@ -2167,8 +2166,6 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char * if (diidx >= dcnt) continue; l1 = lastdir == diidx ? lastdirl : strlen(dn[diidx]); - if (l1 == 0) - continue; l = l1 + strlen(bn[i]) + 1; if (l > spacen) { @@ -2182,12 +2179,16 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char * lastdirl = l1; } strcpy(space + l1, bn[i]); + info.diridx = diidx; + info.dirlen = l1; + if (fm) + info.mode = fm[i]; if (md) { - md5p = md[i]; - if (S_ISLNK(fm[i])) + info.digest = md[i]; + if (fm && S_ISLNK(fm[i])) { - md5p = 0; + info.digest = 0; if (!lt) { lt = headstringarray(rpmhead, TAG_FILELINKTOS, &cnt2); @@ -2197,16 +2198,18 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char * if (lt) { linkhash(lt[i], md5); - md5p = md5; + info.digest = md5; } } - if (!md5p) + if (!info.digest) { sprintf(md5, "%08x%08x%08x%08x", (fm[i] >> 12) & 65535, 0, 0, 0); - md5p = md5; + info.digest = md5; } } - (*cb)(cbdata, space, co ? (fm[i] | co[i] << 24) : fm[i], md5p); + if (co) + info.color = co[i]; + (*cb)(cbdata, space, &info); } solv_free(space); solv_free(lt); diff --git a/ext/repo_rpmdb.h b/ext/repo_rpmdb.h index 79e35c7..e513417 100644 --- a/ext/repo_rpmdb.h +++ b/ext/repo_rpmdb.h @@ -44,6 +44,15 @@ extern void *rpm_byfp(void *rpmstate, FILE *fp, const char *name); extern void *rpm_byrpmh(void *rpmstate, struct headerToken_s *h); /* operations on a rpm header handle */ + +struct filelistinfo { + unsigned int dirlen; + unsigned int diridx; + const char *digest; + unsigned int mode; + unsigned int color; +}; + extern char *rpm_query(void *rpmhandle, Id what); -extern void rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *, int, const char *), void *cbdata); +extern void rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *, struct filelistinfo *), void *cbdata); extern Id repo_add_rpm_handle(Repo *repo, void *rpmhandle, int flags); |