summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorewt <devnull@localhost>1998-12-30 16:56:28 +0000
committerewt <devnull@localhost>1998-12-30 16:56:28 +0000
commitd7ad76b4fcea79a327c5ef49ad28d1c116c66117 (patch)
tree9c4655e2068829cbc0d09a82ceddac3b4e70edec
parent61a2cbcabfaea2b3f36d7eb1759aab61a935ce80 (diff)
downloadrpm-d7ad76b4fcea79a327c5ef49ad28d1c116c66117.tar.gz
rpm-d7ad76b4fcea79a327c5ef49ad28d1c116c66117.tar.bz2
rpm-d7ad76b4fcea79a327c5ef49ad28d1c116c66117.zip
added fpLookupList()
CVS patchset: 2623 CVS date: 1998/12/30 16:56:28
-rw-r--r--lib/fprint.c85
-rw-r--r--lib/fprint.h3
2 files changed, 87 insertions, 1 deletions
diff --git a/lib/fprint.c b/lib/fprint.c
index 87c1c49e8..7a6ff8af4 100644
--- a/lib/fprint.c
+++ b/lib/fprint.c
@@ -4,18 +4,65 @@
#include "fprint.h"
+struct lookupCache {
+ char * match;
+ int pathsStripped;
+ int matchLength;
+ dev_t dev;
+ ino_t ino;
+};
+
+static fingerPrint doLookup(char * fullName, int scareMemory,
+ struct lookupCache * cache);
+
+static int strCompare(const void * a, const void * b) {
+ const char * const * one = a;
+ const char * const * two = a;
+
+ return strcmp(*one, *two);
+};
+
fingerPrint fpLookup(char * fullName, int scareMemory) {
+ return doLookup(fullName, scareMemory, NULL);
+}
+
+static fingerPrint doLookup(char * fullName, int scareMemory,
+ struct lookupCache * cache) {
char dir[PATH_MAX];
char * chptr1, * end;
fingerPrint fp;
struct stat sb;
char * buf;
+ int stripCount;
/* assert(*fullName == '/' || !scareMemory); */
/* FIXME: a directory stat cache could *really* speed things up. we'd
have to be sure to flush it, but... */
+ if (cache && cache->pathsStripped &&
+ !strncmp(fullName, cache->match, cache->matchLength)) {
+ chptr1 = fullName + cache->matchLength;
+ if (*chptr1 == '/') {
+ chptr1++;
+ stripCount = cache->pathsStripped - 1;
+ while (*chptr1) {
+ if (*chptr1 == '/') stripCount--;
+ chptr1++;
+ }
+ if (!stripCount) {
+ chptr1 = fullName + cache->matchLength + 1;
+ if (scareMemory)
+ fp.basename = strdup(chptr1);
+ else
+ fp.basename = chptr1;
+ fp.ino = cache->ino;
+ fp.dev = cache->dev;
+ return fp;
+ }
+ }
+ }
+
if (*fullName != '/') {
scareMemory = 0;
@@ -40,8 +87,10 @@ fingerPrint fpLookup(char * fullName, int scareMemory) {
buf = alloca(strlen(fullName) + 1);
strcpy(buf, fullName);
end = strrchr(buf, '/');
+ stripCount = 0;
while (*buf) {
*end = '\0';
+ stripCount++;
/* as we're stating paths here, we want to follow symlinks */
if (!stat(buf, &sb)) {
@@ -52,10 +101,19 @@ fingerPrint fpLookup(char * fullName, int scareMemory) {
fp.basename = chptr1;
fp.ino = sb.st_ino;
fp.dev = sb.st_dev;
+
+ if (cache) {
+ strcpy(cache->match, buf);
+ cache->matchLength = strlen(buf);
+ cache->pathsStripped = stripCount;
+ cache->dev = sb.st_dev;
+ cache->ino = sb.st_ino;
+ }
+
return fp;
}
- buf--;
+ end--;
while ((end > buf) && *end != '/') end--;
}
@@ -86,3 +144,28 @@ unsigned int fpHashFunction(const void * key) {
int fpEqual(const void * key1, const void * key2) {
return FP_EQUAL(*((const fingerPrint *) key1), *((fingerPrint *) key2));
}
+
+void fpLookupList(char ** fullNames, fingerPrint * fpList, int numItems,
+ int alreadySorted) {
+ int i, j;
+ struct lookupCache cache;
+ int maxLen = 0;
+
+ if (!alreadySorted) {
+ qsort(fullNames, numItems, sizeof(char *), strCompare);
+ }
+
+ for (i = 0; i < numItems; i++) {
+ j = strlen(fullNames[i]);
+ if (j > maxLen) maxLen = j;
+ }
+
+ cache.match = alloca(maxLen + 1);
+ *cache.match = '\0';
+ cache.matchLength = 0;
+ cache.pathsStripped = 0;
+
+ for (i = 0; i < numItems; i++) {
+ fpList[i] = doLookup(fullNames[i], 1, &cache);
+ }
+}
diff --git a/lib/fprint.h b/lib/fprint.h
index fab0a3fe0..aafb0a81d 100644
--- a/lib/fprint.h
+++ b/lib/fprint.h
@@ -11,6 +11,9 @@ typedef struct fingerprint_s {
fingerPrint fpLookup(char * fullName, int scareMemory);
unsigned int fpHashFunction(const void * string);
int fpEqual(const void * key1, const void * key2);
+/* scareMemory is assumed here! */
+void fpLookupList(char ** fullNames, fingerPrint * fpList, int numItems,
+ int alreadySorted);
/* only if !scarceMemory */
#define fpFree(a) free((a).basename)