diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2012-09-13 22:19:40 +0300 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2012-09-14 13:32:58 +0300 |
commit | d3de5120b7930d1d2abf99b7c4a315b4053d702d (patch) | |
tree | 40421de96d9e305b66184ef7868bd5311508b70f /lib/fprint.c | |
parent | 33b900fc03486e5cf3fd22373cf3187fbdffbea0 (diff) | |
download | rpm-d3de5120b7930d1d2abf99b7c4a315b4053d702d.tar.gz |
Move the entire fingerprint cache population into fprint.c
- Rename addFingerprints() to fpCachePopulate() and move into fprint.c.
This doesn't really belong here as it requires fprint becoming aware
of transactions and all, but at least these are all controlled API
accesses unlike where in transaction.c this was messing with somebody
elses data structures directly.
- Move the by-fingerprint creation to fpCachePopulate() so it gets
lazily done as needed and copy the original hash-size heuristics
back here.
Diffstat (limited to 'lib/fprint.c')
-rw-r--r-- | lib/fprint.c | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/lib/fprint.c b/lib/fprint.c index f72a149f8..e6aa42bcd 100644 --- a/lib/fprint.c +++ b/lib/fprint.c @@ -5,9 +5,12 @@ #include "system.h" #include <rpm/rpmfileutil.h> /* for rpmCleanPath */ +#include <rpm/rpmts.h> +#include <rpm/rpmdb.h> #include "lib/rpmdb_internal.h" #include "lib/rpmfi_internal.h" +#include "lib/rpmte_internal.h" #include "lib/fprint.h" #include "lib/misc.h" #include "debug.h" @@ -40,8 +43,6 @@ fingerPrintCache fpCacheCreate(int sizeHint) fpc->ht = rpmFpEntryHashCreate(sizeHint, rstrhash, strcmp, (rpmFpEntryHashFreeKey)free, (rpmFpEntryHashFreeData)free); - fpc->fp = rpmFpHashCreate(sizeHint, fpHashFunction, fpEqual, - NULL, NULL); return fpc; } @@ -368,3 +369,71 @@ int fpCacheGetByFp(fingerPrintCache cache, struct fingerPrint_s * fp, { return rpmFpHashGetEntry(cache->fp, fp, recs, numRecs, NULL); } + +void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount) +{ + rpmtsi pi; + rpmte p; + rpmfs fs; + rpmfi fi; + int i, fc; + + if (fpc->fp == NULL) + fpc->fp = rpmFpHashCreate(fileCount/2 + 10001, fpHashFunction, fpEqual, + NULL, NULL); + + rpmFpHash symlinks = rpmFpHashCreate(fileCount/16+16, fpHashFunction, fpEqual, NULL, NULL); + + pi = rpmtsiInit(ts); + while ((p = rpmtsiNext(pi, 0)) != NULL) { + (void) rpmdbCheckSignals(); + + if ((fi = rpmteFI(p)) == NULL) + continue; /* XXX can't happen */ + + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); + rpmfiFpLookup(fi, fpc); + fs = rpmteGetFileStates(p); + fc = rpmfsFC(fs); + /* collect symbolic links */ + for (i = 0; i < fc; i++) { + struct rpmffi_s ffi; + char const *linktarget; + if (XFA_SKIPPING(rpmfsGetAction(fs, i))) + continue; + linktarget = rpmfiFLinkIndex(fi, i); + if (!(linktarget && *linktarget != '\0')) + continue; + ffi.p = p; + ffi.fileno = i; + rpmFpHashAddEntry(symlinks, rpmfiFpsIndex(fi, i), ffi); + } + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc); + + } + rpmtsiFree(pi); + + /* =============================================== + * Check fingerprints if they contain symlinks + * and add them to the hash table + */ + + pi = rpmtsiInit(ts); + while ((p = rpmtsiNext(pi, 0)) != NULL) { + (void) rpmdbCheckSignals(); + + fs = rpmteGetFileStates(p); + fc = rpmfsFC(fs); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); + for (i = 0; i < fc; i++) { + if (XFA_SKIPPING(rpmfsGetAction(fs, i))) + continue; + fpLookupSubdir(symlinks, fpc, p, i); + } + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); + } + rpmtsiFree(pi); + + rpmFpHashFree(symlinks); +} + |