summaryrefslogtreecommitdiff
path: root/lib/fprint.c
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2012-09-13 22:19:40 +0300
committerPanu Matilainen <pmatilai@redhat.com>2012-09-14 13:32:58 +0300
commitd3de5120b7930d1d2abf99b7c4a315b4053d702d (patch)
tree40421de96d9e305b66184ef7868bd5311508b70f /lib/fprint.c
parent33b900fc03486e5cf3fd22373cf3187fbdffbea0 (diff)
downloadrpm-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.c73
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);
+}
+